diff --git a/.gitignore b/.gitignore
index 431b9e0bcedb9a1c51376555882b0f4da06fb54d..dd8ad6fc9f8427efea3cd9df3720d9a10af35050 100644
--- a/.gitignore
+++ b/.gitignore
@@ -127,5 +127,8 @@ test_gnur
 test_fastr
 lib.install.cran*
 package.blacklist
+*.ll
+*.su
+*.bc
 com.oracle.truffle.r.test.native/embedded/lib
 bench-results.json
diff --git a/README.md b/README.md
index 2a3bd788d9cbfccfae841a0e832fe6cdf18b822f..c0ed367874ca9a01fa2f8dc980cb31c3503111cf 100644
--- a/README.md
+++ b/README.md
@@ -30,7 +30,7 @@ FastR is primarily aimed at long-running applications. The runtime performance b
 
 Building FastR from source is supported on Mac OS X (El Capitan onwards), and various flavors of Linux.
 FastR uses a build tool called `mx` (cf `maven`) which can be downloaded from [here](http://github.com/graalvm/mx).
-`mx` manages software in _suites_, which are normally one-to-one with a `git` repository. FastR depends fundamentally on the [truffle](http://github.com/graalvm/truffle) suite. However, performance also depends on the [graal compiler](http://github.com/graalvm/graal-core) as without it, FastR operates in interpreted mode only. The conventional way to arrange the Git repos (suites) is as siblings in a parent directory, which we will call `FASTR_HOME`.
+`mx` manages software in _suites_, which are normally one-to-one with a `git` repository. FastR depends fundamentally on the [truffle](http://github.com/graalvm/truffle) suite. However, performance also depends on the [Graal compiler](http://github.com/graalvm/graal-core) as without it, FastR operates in interpreted mode only. The conventional way to arrange the Git repos (suites) is as siblings in a parent directory, which we will call `FASTR_HOME`.
 
 ## Pre-Requisites
 FastR shares some code with GnuR, for example, the default packages and the Blas library. Therefore, a version of GnuR (currently
@@ -74,7 +74,14 @@ Use the following sequence of commands to download and build an interpreted vers
 	$ cd fastr
 	$ mx build
 
-The build will clone the Truffle repository and also download various required libraries.
+The build will clone the Truffle repository and also download various required libraries, including GNU R, which is built first. Any problems with the GNU R configure step likely relate
+to dependent packages, so review the previous section. For FastR development, GNU R only needs to be built once, but an `mx clean` will, by default remove it. This can be prevented by setting
+the `GNUR_NOCLEAN` environment variable to any value.
+
+It is possible to build FastR in "release mode" which builds and installs the GNU R "recommended" packages and also creates a `fastr-release.jar` file that contains everything that is needed to
+run FastR, apart from a Java VM. In particular it captures the package dependencies, e.g., `pcre` and `libgfortran`, so that when the file is unpacked on another system it will work regardless of whether the packages are installed on that system. For some systems that depend on FastR, e.g., GraalVM, it is a requirement to build in release mode as they depend on this file. To build in release mode, set the `FASTR_RELEASE` environment variable to any value. Note that this can be done at any time without doing a complete clean and rebuild. Simply set the variable and execute `mx build`.
+
+## Running FastR
 
 After building, running the FastR console can be done either with `bin/R` or  with `mx r` or `mx R`. Using `mx` makes available some additional options that are of interest to FastR developers.
 FastR supports the same command line arguments as R, so running an R script is done with `bin/R -f <file>` or `bin/Rscript <file>`.
@@ -85,7 +92,7 @@ FastR supports the same command line arguments as R, so running an R script is d
 
 ## Further Documentation
 
-Further documentation on FastR, its limitations and additional functionality is [here](Index.md).
+Further documentation on FastR, its limitations and additional functionality is [here](documentation/Index.md).
 
 ## Contributing
 
diff --git a/com.oracle.truffle.r.engine/src/com/oracle/truffle/r/engine/REngine.java b/com.oracle.truffle.r.engine/src/com/oracle/truffle/r/engine/REngine.java
index ee090e1c1ac7134433c540a1242dc2a56006ab89..e586514fd40b7edc29e0032580acd2088be19fa1 100644
--- a/com.oracle.truffle.r.engine/src/com/oracle/truffle/r/engine/REngine.java
+++ b/com.oracle.truffle.r.engine/src/com/oracle/truffle/r/engine/REngine.java
@@ -40,6 +40,8 @@ import com.oracle.truffle.api.frame.FrameDescriptor;
 import com.oracle.truffle.api.frame.MaterializedFrame;
 import com.oracle.truffle.api.frame.VirtualFrame;
 import com.oracle.truffle.api.interop.TruffleObject;
+import com.oracle.truffle.api.nodes.DirectCallNode;
+import com.oracle.truffle.api.nodes.ExplodeLoop;
 import com.oracle.truffle.api.nodes.Node;
 import com.oracle.truffle.api.nodes.RootNode;
 import com.oracle.truffle.api.profiles.ConditionProfile;
@@ -291,9 +293,9 @@ final class REngine implements Engine, Engine.Timings {
     }
 
     @Override
-    public CallTarget parseToCallTarget(Source source) throws ParseException {
+    public CallTarget parseToCallTarget(Source source, MaterializedFrame executionFrame) throws ParseException {
         List<RSyntaxNode> statements = parseImpl(source);
-        return Truffle.getRuntime().createCallTarget(new PolyglotEngineRootNode(statements, createSourceSection(statements)));
+        return Truffle.getRuntime().createCallTarget(new PolyglotEngineRootNode(statements, createSourceSection(statements), executionFrame));
     }
 
     private static SourceSection createSourceSection(List<RSyntaxNode> statements) {
@@ -309,15 +311,19 @@ final class REngine implements Engine, Engine.Timings {
     private final class PolyglotEngineRootNode extends RootNode {
 
         private final List<RSyntaxNode> statements;
+        private final MaterializedFrame executionFrame;
+        @Children private final DirectCallNode[] calls;
         private final boolean printResult;
 
         @Child private Node findContext = TruffleRLanguage.INSTANCE.actuallyCreateFindContextNode();
 
-        PolyglotEngineRootNode(List<RSyntaxNode> statements, SourceSection sourceSection) {
+        PolyglotEngineRootNode(List<RSyntaxNode> statements, SourceSection sourceSection, MaterializedFrame executionFrame) {
             super(TruffleRLanguage.class, sourceSection, new FrameDescriptor());
             // can't print if initializing the system in embedded mode (no builtins yet)
             this.printResult = !sourceSection.getSource().getName().equals(RSource.Internal.INIT_EMBEDDED.string);
             this.statements = statements;
+            this.executionFrame = executionFrame;
+            this.calls = new DirectCallNode[statements.size()];
         }
 
         /**
@@ -326,6 +332,7 @@ final class REngine implements Engine, Engine.Timings {
          * control over what that might be when the call is initiated.
          */
         @Override
+        @ExplodeLoop
         public Object execute(VirtualFrame frame) {
             RContext oldContext = RContext.getThreadLocalInstance();
             RContext newContext = TruffleRLanguage.INSTANCE.actuallyFindContext0(findContext);
@@ -334,8 +341,11 @@ final class REngine implements Engine, Engine.Timings {
                 Object lastValue = RNull.instance;
                 for (int i = 0; i < statements.size(); i++) {
                     RSyntaxNode node = statements.get(i);
-                    RootCallTarget callTarget = doMakeCallTarget(node.asRNode(), RSource.Internal.REPL_WRAPPER.string, printResult, true);
-                    lastValue = callTarget.call(newContext.stateREnvironment.getGlobalFrame());
+                    if (calls[i] == null) {
+                        CompilerDirectives.transferToInterpreterAndInvalidate();
+                        calls[i] = insert(Truffle.getRuntime().createDirectCallNode(doMakeCallTarget(node.asRNode(), RSource.Internal.REPL_WRAPPER.string, printResult, true)));
+                    }
+                    lastValue = calls[i].call(frame, new Object[]{executionFrame != null ? executionFrame : newContext.stateREnvironment.getGlobalFrame()});
                 }
                 return lastValue;
             } catch (ReturnException ex) {
@@ -526,7 +536,7 @@ final class REngine implements Engine, Engine.Timings {
                 if (topLevel) {
                     RErrorHandling.printWarnings(suppressWarnings);
                 }
-                setVisibility.executeEndOfFunction(vf);
+                setVisibility.executeEndOfFunction(vf, this);
             } catch (RError e) {
                 CompilerDirectives.transferToInterpreter();
                 throw e;
@@ -558,6 +568,11 @@ final class REngine implements Engine, Engine.Timings {
             return result;
         }
 
+        @Override
+        public String getName() {
+            return description;
+        }
+
         @Override
         public String toString() {
             return description;
diff --git a/com.oracle.truffle.r.engine/src/com/oracle/truffle/r/engine/TruffleRLanguage.java b/com.oracle.truffle.r.engine/src/com/oracle/truffle/r/engine/TruffleRLanguage.java
index b61eb0c18adc3fbbf422abfe61354c97fd53cbe4..f7561e6d6580bd489e41fe5f8692b55bcd34c9e8 100644
--- a/com.oracle.truffle.r.engine/src/com/oracle/truffle/r/engine/TruffleRLanguage.java
+++ b/com.oracle.truffle.r.engine/src/com/oracle/truffle/r/engine/TruffleRLanguage.java
@@ -25,18 +25,16 @@ package com.oracle.truffle.r.engine;
 import java.util.Locale;
 
 import com.oracle.truffle.api.CallTarget;
-import com.oracle.truffle.api.CompilerDirectives.TruffleBoundary;
+import com.oracle.truffle.api.CompilerAsserts;
 import com.oracle.truffle.api.Truffle;
 import com.oracle.truffle.api.TruffleLanguage;
 import com.oracle.truffle.api.frame.FrameDescriptor;
-import com.oracle.truffle.api.frame.MaterializedFrame;
 import com.oracle.truffle.api.frame.VirtualFrame;
 import com.oracle.truffle.api.instrumentation.Instrumenter;
 import com.oracle.truffle.api.instrumentation.ProvidedTags;
 import com.oracle.truffle.api.instrumentation.StandardTags;
 import com.oracle.truffle.api.nodes.Node;
 import com.oracle.truffle.api.nodes.RootNode;
-import com.oracle.truffle.api.source.Source;
 import com.oracle.truffle.r.engine.interop.RForeignAccessFactoryImpl;
 import com.oracle.truffle.r.nodes.RASTBuilder;
 import com.oracle.truffle.r.nodes.builtin.RBuiltinPackages;
@@ -141,13 +139,13 @@ public final class TruffleRLanguage extends TruffleLanguage<RContext> {
         return null;
     }
 
-    @Override
-    @TruffleBoundary
     @SuppressWarnings("try")
-    protected CallTarget parse(Source source, Node context, String... argumentNames) throws com.oracle.truffle.api.vm.IncompleteSourceException {
+    @Override
+    protected CallTarget parse(ParsingRequest request) throws Exception {
+        CompilerAsserts.neverPartOfCompilation();
         try (RCloseable c = RContext.withinContext(findContext(createFindContextNode()))) {
             try {
-                return RContext.getEngine().parseToCallTarget(source);
+                return RContext.getEngine().parseToCallTarget(request.getSource(), request.getFrame());
             } catch (IncompleteSourceException e) {
                 throw new com.oracle.truffle.api.vm.IncompleteSourceException(e);
             } catch (ParseException e) {
@@ -191,9 +189,4 @@ public final class TruffleRLanguage extends TruffleLanguage<RContext> {
     public RContext actuallyFindContext0(Node contextNode) {
         return findContext(contextNode);
     }
-
-    @Override
-    protected Object evalInContext(Source source, Node node, MaterializedFrame frame) {
-        return RContext.getEngine().parseAndEval(source, frame, false);
-    }
 }
diff --git a/com.oracle.truffle.r.engine/src/com/oracle/truffle/r/engine/interop/NativeCharArray.java b/com.oracle.truffle.r.engine/src/com/oracle/truffle/r/engine/interop/NativeCharArray.java
new file mode 100644
index 0000000000000000000000000000000000000000..582860ac3d948d2448f6aa8427f61f3027b9467d
--- /dev/null
+++ b/com.oracle.truffle.r.engine/src/com/oracle/truffle/r/engine/interop/NativeCharArray.java
@@ -0,0 +1,37 @@
+/*
+ * Copyright (c) 2014, 2016, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package com.oracle.truffle.r.engine.interop;
+
+import com.oracle.truffle.api.interop.TruffleObject;
+
+/**
+ * A {@link TruffleObject} that represents an array of {@code unsigned char} values, that is
+ * {@code NULL} terminated in the C domain.
+ */
+public class NativeCharArray extends NativeUInt8Array {
+
+    public NativeCharArray(byte[] bytes) {
+        super(bytes, true);
+    }
+
+}
diff --git a/com.oracle.truffle.r.engine/src/com/oracle/truffle/r/engine/interop/NativeCharArrayMR.java b/com.oracle.truffle.r.engine/src/com/oracle/truffle/r/engine/interop/NativeCharArrayMR.java
new file mode 100644
index 0000000000000000000000000000000000000000..5e8e040221f1f747c101648f8d2ea91dc2143e50
--- /dev/null
+++ b/com.oracle.truffle.r.engine/src/com/oracle/truffle/r/engine/interop/NativeCharArrayMR.java
@@ -0,0 +1,78 @@
+/*
+ * Copyright (c) 2014, 2016, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package com.oracle.truffle.r.engine.interop;
+
+import com.oracle.truffle.api.interop.CanResolve;
+import com.oracle.truffle.api.interop.MessageResolution;
+import com.oracle.truffle.api.interop.Resolve;
+import com.oracle.truffle.api.interop.TruffleObject;
+import com.oracle.truffle.api.nodes.Node;
+import com.oracle.truffle.r.engine.TruffleRLanguage;
+
+@MessageResolution(receiverType = NativeCharArray.class, language = TruffleRLanguage.class)
+public class NativeCharArrayMR {
+    @Resolve(message = "READ")
+    public abstract static class NCAReadNode extends Node {
+        protected byte access(NativeCharArray receiver, int index) {
+            return receiver.read(index);
+        }
+    }
+
+    @Resolve(message = "WRITE")
+    public abstract static class NCAWriteNode extends Node {
+        protected Object access(NativeCharArray receiver, int index, byte value) {
+            receiver.write(index, value);
+            return value;
+        }
+    }
+
+    @Resolve(message = "HAS_SIZE")
+    public abstract static class NCAHasSizeNode extends Node {
+        protected boolean access(@SuppressWarnings("unused") NativeCharArray receiver) {
+            return true;
+        }
+    }
+
+    @Resolve(message = "GET_SIZE")
+    public abstract static class NCAGetSizeNode extends Node {
+        protected int access(NativeCharArray receiver) {
+            return receiver.getSize();
+        }
+    }
+
+    @Resolve(message = "UNBOX")
+    public abstract static class NCAUnboxNode extends Node {
+        protected long access(NativeCharArray receiver) {
+            return receiver.convertToNative();
+        }
+    }
+
+    @CanResolve
+    public abstract static class NCACheck extends Node {
+
+        protected static boolean test(TruffleObject receiver) {
+            return receiver instanceof NativeCharArray;
+        }
+    }
+
+}
diff --git a/com.oracle.truffle.r.engine/src/com/oracle/truffle/r/engine/interop/NativeDoubleArray.java b/com.oracle.truffle.r.engine/src/com/oracle/truffle/r/engine/interop/NativeDoubleArray.java
new file mode 100644
index 0000000000000000000000000000000000000000..471fe62d1a061b11ee3879509c8ffa8fd7598b59
--- /dev/null
+++ b/com.oracle.truffle.r.engine/src/com/oracle/truffle/r/engine/interop/NativeDoubleArray.java
@@ -0,0 +1,39 @@
+/*
+ * Copyright (c) 2016, 2016, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package com.oracle.truffle.r.engine.interop;
+
+import com.oracle.truffle.r.runtime.data.RTruffleObject;
+
+public class NativeDoubleArray extends NativeNACheck implements RTruffleObject {
+    public final double[] value;
+
+    public NativeDoubleArray(Object obj, double[] value) {
+        super(obj);
+        this.value = value;
+    }
+
+    public NativeDoubleArray(double[] value) {
+        this(null, value);
+    }
+
+}
diff --git a/com.oracle.truffle.r.engine/src/com/oracle/truffle/r/engine/interop/NativeDoubleArrayMR.java b/com.oracle.truffle.r.engine/src/com/oracle/truffle/r/engine/interop/NativeDoubleArrayMR.java
new file mode 100644
index 0000000000000000000000000000000000000000..573bdb61008a581c770c3396df82334d5e87acbc
--- /dev/null
+++ b/com.oracle.truffle.r.engine/src/com/oracle/truffle/r/engine/interop/NativeDoubleArrayMR.java
@@ -0,0 +1,61 @@
+/*
+ * Copyright (c) 2016, 2016, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package com.oracle.truffle.r.engine.interop;
+
+import com.oracle.truffle.api.interop.CanResolve;
+import com.oracle.truffle.api.interop.MessageResolution;
+import com.oracle.truffle.api.interop.Resolve;
+import com.oracle.truffle.api.interop.TruffleObject;
+import com.oracle.truffle.api.nodes.Node;
+import com.oracle.truffle.r.engine.TruffleRLanguage;
+import com.oracle.truffle.r.runtime.RRuntime;
+
+@MessageResolution(receiverType = NativeDoubleArray.class, language = TruffleRLanguage.class)
+public class NativeDoubleArrayMR {
+
+    @Resolve(message = "READ")
+    public abstract static class NDAReadNode extends Node {
+        protected double access(NativeDoubleArray receiver, int index) {
+            return receiver.value[index];
+        }
+    }
+
+    @Resolve(message = "WRITE")
+    public abstract static class NDAWriteNode extends Node {
+        protected double access(NativeDoubleArray receiver, int index, double value) {
+            if (value == RRuntime.DOUBLE_NA) {
+                receiver.setIncomplete();
+            }
+            receiver.value[index] = value;
+            return value;
+        }
+    }
+
+    @CanResolve
+    public abstract static class NDACheck extends Node {
+
+        protected static boolean test(TruffleObject receiver) {
+            return receiver instanceof NativeDoubleArray;
+        }
+    }
+}
diff --git a/com.oracle.truffle.r.engine/src/com/oracle/truffle/r/engine/interop/NativeIntegerArray.java b/com.oracle.truffle.r.engine/src/com/oracle/truffle/r/engine/interop/NativeIntegerArray.java
new file mode 100644
index 0000000000000000000000000000000000000000..ee20f7db3ef49404a4408daef761af4e795fac82
--- /dev/null
+++ b/com.oracle.truffle.r.engine/src/com/oracle/truffle/r/engine/interop/NativeIntegerArray.java
@@ -0,0 +1,39 @@
+/*
+ * Copyright (c) 2016, 2016, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package com.oracle.truffle.r.engine.interop;
+
+import com.oracle.truffle.r.runtime.data.RTruffleObject;
+
+public class NativeIntegerArray extends NativeNACheck implements RTruffleObject {
+    public final int[] value;
+
+    public NativeIntegerArray(Object obj, int[] value) {
+        super(obj);
+        this.value = value;
+    }
+
+    public NativeIntegerArray(int[] value) {
+        this(null, value);
+    }
+
+}
diff --git a/com.oracle.truffle.r.engine/src/com/oracle/truffle/r/engine/interop/NativeIntegerArrayMR.java b/com.oracle.truffle.r.engine/src/com/oracle/truffle/r/engine/interop/NativeIntegerArrayMR.java
new file mode 100644
index 0000000000000000000000000000000000000000..70115e5f2dca80144eeb71fdee370b8ab1a8d545
--- /dev/null
+++ b/com.oracle.truffle.r.engine/src/com/oracle/truffle/r/engine/interop/NativeIntegerArrayMR.java
@@ -0,0 +1,62 @@
+/*
+ * Copyright (c) 2016, 2016, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package com.oracle.truffle.r.engine.interop;
+
+import com.oracle.truffle.api.interop.CanResolve;
+import com.oracle.truffle.api.interop.MessageResolution;
+import com.oracle.truffle.api.interop.Resolve;
+import com.oracle.truffle.api.interop.TruffleObject;
+import com.oracle.truffle.api.nodes.Node;
+import com.oracle.truffle.r.engine.TruffleRLanguage;
+import com.oracle.truffle.r.runtime.RRuntime;
+
+@MessageResolution(receiverType = NativeIntegerArray.class, language = TruffleRLanguage.class)
+public class NativeIntegerArrayMR {
+
+    @Resolve(message = "READ")
+    public abstract static class NIAReadNode extends Node {
+        protected int access(NativeIntegerArray receiver, int index) {
+            return receiver.value[index];
+        }
+    }
+
+    @Resolve(message = "WRITE")
+    public abstract static class NIAWriteNode extends Node {
+        protected int access(NativeIntegerArray receiver, int index, int value) {
+            if (value == RRuntime.INT_NA) {
+                receiver.setIncomplete();
+            }
+            receiver.value[index] = value;
+            return value;
+        }
+    }
+
+    @CanResolve
+    public abstract static class NIACheck extends Node {
+
+        protected static boolean test(TruffleObject receiver) {
+            return receiver instanceof NativeIntegerArray;
+        }
+    }
+
+}
diff --git a/com.oracle.truffle.r.engine/src/com/oracle/truffle/r/engine/interop/NativeLogicalArray.java b/com.oracle.truffle.r.engine/src/com/oracle/truffle/r/engine/interop/NativeLogicalArray.java
new file mode 100644
index 0000000000000000000000000000000000000000..bc1e41f398dbfcab2819e660432117dd6286b330
--- /dev/null
+++ b/com.oracle.truffle.r.engine/src/com/oracle/truffle/r/engine/interop/NativeLogicalArray.java
@@ -0,0 +1,56 @@
+/*
+ * Copyright (c) 2014, 2016, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package com.oracle.truffle.r.engine.interop;
+
+import com.oracle.truffle.api.CompilerDirectives.CompilationFinal;
+import com.oracle.truffle.r.runtime.RRuntime;
+import com.oracle.truffle.r.runtime.data.RTruffleObject;
+
+/**
+ * Handles the requirement that the R FFI sees "logical" arrays as {@code int[]} but the actual
+ * array in FastR is represented as {@code byte[]}.
+ */
+public class NativeLogicalArray extends NativeNACheck implements RTruffleObject {
+    @CompilationFinal public final byte[] data;
+
+    public NativeLogicalArray(Object obj, byte[] value) {
+        super(obj);
+        this.data = value;
+    }
+
+    int read(int index) {
+        return data[index] & 0xFF;
+    }
+
+    void write(int index, int value) {
+        byte newVal;
+        if (value == RRuntime.INT_NA) {
+            newVal = RRuntime.LOGICAL_NA;
+            setIncomplete();
+        } else {
+            newVal = (byte) (value & 0xFF);
+        }
+        data[index] = newVal;
+    }
+
+}
diff --git a/com.oracle.truffle.r.engine/src/com/oracle/truffle/r/engine/interop/NativeLogicalArrayMR.java b/com.oracle.truffle.r.engine/src/com/oracle/truffle/r/engine/interop/NativeLogicalArrayMR.java
new file mode 100644
index 0000000000000000000000000000000000000000..eb9d9bdae5988b38c75cd26dfba03e86c8d929ea
--- /dev/null
+++ b/com.oracle.truffle.r.engine/src/com/oracle/truffle/r/engine/interop/NativeLogicalArrayMR.java
@@ -0,0 +1,64 @@
+/*
+ * Copyright (c) 2014, 2016, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package com.oracle.truffle.r.engine.interop;
+
+import com.oracle.truffle.api.interop.CanResolve;
+import com.oracle.truffle.api.interop.MessageResolution;
+import com.oracle.truffle.api.interop.Resolve;
+import com.oracle.truffle.api.interop.TruffleObject;
+import com.oracle.truffle.api.nodes.Node;
+import com.oracle.truffle.r.engine.TruffleRLanguage;
+
+@MessageResolution(receiverType = NativeLogicalArray.class, language = TruffleRLanguage.class)
+public class NativeLogicalArrayMR {
+    @Resolve(message = "READ")
+    public abstract static class NLAReadNode extends Node {
+        protected int access(NativeLogicalArray receiver, int index) {
+            return receiver.read(index);
+        }
+    }
+
+    @Resolve(message = "WRITE")
+    public abstract static class NLAWriteNode extends Node {
+        protected Object access(NativeLogicalArray receiver, int index, int value) {
+            receiver.write(index, value);
+            return value;
+        }
+    }
+
+    @Resolve(message = "GET_SIZE")
+    public abstract static class NLAGetSizeNode extends Node {
+        protected int access(NativeLogicalArray receiver) {
+            return receiver.data.length;
+        }
+    }
+
+    @CanResolve
+    public abstract static class NLACheck extends Node {
+
+        protected static boolean test(TruffleObject receiver) {
+            return receiver instanceof NativeLogicalArray;
+        }
+    }
+
+}
diff --git a/com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/stats/Runif.java b/com.oracle.truffle.r.engine/src/com/oracle/truffle/r/engine/interop/NativeNACheck.java
similarity index 59%
rename from com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/stats/Runif.java
rename to com.oracle.truffle.r.engine/src/com/oracle/truffle/r/engine/interop/NativeNACheck.java
index 5701011cf53f8e9f6ee09cae6e6294696b393de8..2eaad54125ea328ba342e4635f02634daacb892d 100644
--- a/com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/stats/Runif.java
+++ b/com.oracle.truffle.r.engine/src/com/oracle/truffle/r/engine/interop/NativeNACheck.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2013, 2016, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2014, 2016, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -20,21 +20,31 @@
  * or visit www.oracle.com if you need additional information or have any
  * questions.
  */
-package com.oracle.truffle.r.library.stats;
+package com.oracle.truffle.r.engine.interop;
 
-import com.oracle.truffle.r.library.stats.RandGenerationFunctions.RandFunction2_Double;
-import com.oracle.truffle.r.library.stats.RandGenerationFunctions.RandomNumberProvider;
-import com.oracle.truffle.r.runtime.RRuntime;
+import com.oracle.truffle.r.runtime.data.RVector;
 
-public final class Runif implements RandFunction2_Double {
-    @Override
-    public double evaluate(double min, double max, RandomNumberProvider rand) {
-        if (!RRuntime.isFinite(min) || !RRuntime.isFinite(max) || max < min) {
-            return RMath.mlError();
+/**
+ * Handles the {@code complete} flag in an {@link RVector} when an {@code NA} value is assigned in
+ * native code.
+ *
+ */
+public class NativeNACheck {
+    private final RVector<?> vec;
+
+    protected NativeNACheck(Object x) {
+        if (x instanceof RVector<?>) {
+            vec = (RVector<?>) x;
+        } else {
+            // scalar (length 1) vector or no associated R object
+            vec = null;
         }
-        if (min == max) {
-            return min;
+    }
+
+    public void setIncomplete() {
+        if (vec != null) {
+            vec.setComplete(false);
         }
-        return min + rand.unifRand() * (max - min);
     }
+
 }
diff --git a/com.oracle.truffle.r.engine/src/com/oracle/truffle/r/engine/interop/NativeRawArray.java b/com.oracle.truffle.r.engine/src/com/oracle/truffle/r/engine/interop/NativeRawArray.java
new file mode 100644
index 0000000000000000000000000000000000000000..8e452be22a8d57901913b6eaf659381bacbcdc05
--- /dev/null
+++ b/com.oracle.truffle.r.engine/src/com/oracle/truffle/r/engine/interop/NativeRawArray.java
@@ -0,0 +1,31 @@
+/*
+ * Copyright (c) 2016, 2016, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package com.oracle.truffle.r.engine.interop;
+
+public class NativeRawArray extends NativeUInt8Array {
+
+    public NativeRawArray(byte[] bytes) {
+        super(bytes, false);
+    }
+
+}
diff --git a/com.oracle.truffle.r.engine/src/com/oracle/truffle/r/engine/interop/NativeRawArrayMR.java b/com.oracle.truffle.r.engine/src/com/oracle/truffle/r/engine/interop/NativeRawArrayMR.java
new file mode 100644
index 0000000000000000000000000000000000000000..4aac34a0afab0c8aeaaba389b4cd3129992afaac
--- /dev/null
+++ b/com.oracle.truffle.r.engine/src/com/oracle/truffle/r/engine/interop/NativeRawArrayMR.java
@@ -0,0 +1,71 @@
+/*
+ * Copyright (c) 2016, 2016, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package com.oracle.truffle.r.engine.interop;
+
+import com.oracle.truffle.api.interop.CanResolve;
+import com.oracle.truffle.api.interop.MessageResolution;
+import com.oracle.truffle.api.interop.Resolve;
+import com.oracle.truffle.api.interop.TruffleObject;
+import com.oracle.truffle.api.nodes.Node;
+import com.oracle.truffle.r.engine.TruffleRLanguage;
+
+@MessageResolution(receiverType = NativeRawArray.class, language = TruffleRLanguage.class)
+public class NativeRawArrayMR {
+    @Resolve(message = "READ")
+    public abstract static class NRAReadNode extends Node {
+        protected byte access(NativeRawArray receiver, int index) {
+            return receiver.bytes[index];
+        }
+    }
+
+    @Resolve(message = "WRITE")
+    public abstract static class NRAWriteNode extends Node {
+        protected Object access(NativeRawArray receiver, int index, byte value) {
+            receiver.bytes[index] = value;
+            return value;
+        }
+    }
+
+    @Resolve(message = "GET_SIZE")
+    public abstract static class NRAGetSizeNode extends Node {
+        protected int access(NativeRawArray receiver) {
+            return receiver.bytes.length;
+        }
+    }
+
+    @Resolve(message = "UNBOX")
+    public abstract static class NRAUnboxNode extends Node {
+        protected long access(NativeRawArray receiver) {
+            return receiver.convertToNative();
+        }
+    }
+
+    @CanResolve
+    public abstract static class NRACheck extends Node {
+
+        protected static boolean test(TruffleObject receiver) {
+            return receiver instanceof NativeRawArray;
+        }
+    }
+
+}
diff --git a/com.oracle.truffle.r.engine/src/com/oracle/truffle/r/engine/interop/NativeUInt8Array.java b/com.oracle.truffle.r.engine/src/com/oracle/truffle/r/engine/interop/NativeUInt8Array.java
new file mode 100644
index 0000000000000000000000000000000000000000..2c8eddabdc7e5a8212846d2759478af031e96b8a
--- /dev/null
+++ b/com.oracle.truffle.r.engine/src/com/oracle/truffle/r/engine/interop/NativeUInt8Array.java
@@ -0,0 +1,118 @@
+/*
+ * Copyright (c) 2016, 2016, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package com.oracle.truffle.r.engine.interop;
+
+import static com.oracle.truffle.r.engine.interop.UnsafeAdapter.UNSAFE;
+
+import com.oracle.truffle.api.CompilerDirectives;
+import com.oracle.truffle.api.CompilerDirectives.CompilationFinal;
+import com.oracle.truffle.r.runtime.data.RTruffleObject;
+
+import sun.misc.Unsafe;
+
+/**
+ * Parent class of {@link NativeRawArray} and {@link NativeCharArray}, that holds the common logic
+ * for a C type {@code uint8*}, that may or may not be {@code NULL} terminated (in the C domain),
+ * and may escape into the native domain via an UNBOX message.
+ *
+ * N.B. Java never stores a {@code NULL} value in a String or the byte array from
+ * {@link String#getBytes}.
+ *
+ * If {@link #fakeNull()} is {@code true}, then {@link #read} returns 0, else it is an error;
+ * similar for {@link #write}.
+ */
+public abstract class NativeUInt8Array implements RTruffleObject {
+    public final byte[] bytes;
+
+    /**
+     * If the array escapes the Truffle world via {@link #convertToNative()}, this value will be
+     * non-zero and is used exclusively thereafter.
+     */
+    @CompilationFinal protected long nativeAddress;
+    private final int effectiveLength;
+
+    protected NativeUInt8Array(byte[] bytes, boolean nullTerminate) {
+        this.bytes = bytes;
+        this.effectiveLength = bytes.length + (nullTerminate ? 1 : 0);
+    }
+
+    private boolean fakeNull() {
+        return bytes.length != effectiveLength;
+    }
+
+    private void checkNativeIndex(int index) {
+        if (index < 0 || index >= effectiveLength) {
+            throw new ArrayIndexOutOfBoundsException(index);
+        }
+    }
+
+    void write(int index, byte value) {
+        if (nativeAddress != 0) {
+            checkNativeIndex(index);
+            UNSAFE.putByte(nativeAddress + index, value);
+        } else {
+            if (index == bytes.length && fakeNull()) {
+                // ignore
+            } else {
+                bytes[index] = value;
+            }
+        }
+    }
+
+    byte read(int index) {
+        if (nativeAddress != 0) {
+            checkNativeIndex(index);
+            return UNSAFE.getByte(nativeAddress + index);
+        } else {
+            if (index == bytes.length && fakeNull()) {
+                return (byte) 0;
+            }
+            return bytes[index];
+        }
+    }
+
+    int getSize() {
+        return bytes.length;
+    }
+
+    long convertToNative() {
+        if (nativeAddress == 0) {
+            CompilerDirectives.transferToInterpreterAndInvalidate();
+            nativeAddress = UNSAFE.allocateMemory(effectiveLength);
+            UNSAFE.copyMemory(bytes, Unsafe.ARRAY_BYTE_BASE_OFFSET, null, nativeAddress, bytes.length);
+            if (fakeNull()) {
+                UNSAFE.putByte(nativeAddress + bytes.length, (byte) 0);
+            }
+        }
+        return nativeAddress;
+    }
+
+    public byte[] getBytes() {
+        if (nativeAddress != 0) {
+            // copy back
+            UNSAFE.copyMemory(null, nativeAddress, bytes, Unsafe.ARRAY_BYTE_BASE_OFFSET, bytes.length);
+        }
+        return bytes;
+    }
+
+}
diff --git a/com.oracle.truffle.r.engine/src/com/oracle/truffle/r/engine/interop/RDoubleMR.java b/com.oracle.truffle.r.engine/src/com/oracle/truffle/r/engine/interop/RDoubleMR.java
new file mode 100644
index 0000000000000000000000000000000000000000..2cacef289c49c07e09543f6894cc1fdf69a4b125
--- /dev/null
+++ b/com.oracle.truffle.r.engine/src/com/oracle/truffle/r/engine/interop/RDoubleMR.java
@@ -0,0 +1,71 @@
+/*
+ * Copyright (c) 2016, 2016, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package com.oracle.truffle.r.engine.interop;
+
+import com.oracle.truffle.api.interop.CanResolve;
+import com.oracle.truffle.api.interop.MessageResolution;
+import com.oracle.truffle.api.interop.Resolve;
+import com.oracle.truffle.api.interop.TruffleObject;
+import com.oracle.truffle.api.nodes.Node;
+import com.oracle.truffle.r.engine.TruffleRLanguage;
+import com.oracle.truffle.r.runtime.data.RDouble;
+
+@MessageResolution(receiverType = RDouble.class, language = TruffleRLanguage.class)
+public class RDoubleMR {
+    @Resolve(message = "IS_BOXED")
+    public abstract static class RDoubleIsBoxedNode extends Node {
+        protected Object access(@SuppressWarnings("unused") RDouble receiver) {
+            return true;
+        }
+    }
+
+    @Resolve(message = "HAS_SIZE")
+    public abstract static class RDoubleHasSizeNode extends Node {
+        protected Object access(@SuppressWarnings("unused") RDouble receiver) {
+            return false;
+        }
+    }
+
+    @Resolve(message = "IS_NULL")
+    public abstract static class RDoubleIsNullNode extends Node {
+        protected Object access(@SuppressWarnings("unused") RDouble receiver) {
+            return false;
+        }
+    }
+
+    @Resolve(message = "UNBOX")
+    public abstract static class RDoubleUnboxNode extends Node {
+        protected double access(RDouble receiver) {
+            return receiver.getValue();
+        }
+    }
+
+    @CanResolve
+    public abstract static class RDoubleCheck extends Node {
+
+        protected static boolean test(TruffleObject receiver) {
+            return receiver instanceof RDouble;
+        }
+    }
+
+}
diff --git a/com.oracle.truffle.r.engine/src/com/oracle/truffle/r/engine/interop/RForeignAccessFactoryImpl.java b/com.oracle.truffle.r.engine/src/com/oracle/truffle/r/engine/interop/RForeignAccessFactoryImpl.java
index 4e2a81101dde3a94799a5219af80a090d17c33e3..d2ada23dadab7250f52af9b9799169c49efb32f7 100644
--- a/com.oracle.truffle.r.engine/src/com/oracle/truffle/r/engine/interop/RForeignAccessFactoryImpl.java
+++ b/com.oracle.truffle.r.engine/src/com/oracle/truffle/r/engine/interop/RForeignAccessFactoryImpl.java
@@ -38,12 +38,14 @@ import com.oracle.truffle.r.runtime.context.RContext;
 import com.oracle.truffle.r.runtime.context.RForeignAccessFactory;
 import com.oracle.truffle.r.runtime.data.RComplex;
 import com.oracle.truffle.r.runtime.data.RComplexVector;
+import com.oracle.truffle.r.runtime.data.RDouble;
 import com.oracle.truffle.r.runtime.data.RDoubleSequence;
 import com.oracle.truffle.r.runtime.data.RDoubleVector;
 import com.oracle.truffle.r.runtime.data.RExternalPtr;
 import com.oracle.truffle.r.runtime.data.RFunction;
 import com.oracle.truffle.r.runtime.data.RIntSequence;
 import com.oracle.truffle.r.runtime.data.RIntVector;
+import com.oracle.truffle.r.runtime.data.RInteger;
 import com.oracle.truffle.r.runtime.data.RList;
 import com.oracle.truffle.r.runtime.data.RLogicalVector;
 import com.oracle.truffle.r.runtime.data.RNull;
@@ -99,7 +101,10 @@ public final class RForeignAccessFactoryImpl implements RForeignAccessFactory {
                     RFunction.class, RNull.class, REnvironment.class,
                     RList.class, RSymbol.class,
                     RPairList.class, RExternalPtr.class, RUnboundValue.class,
-                    DLLInfo.class, DotSymbol.class};
+                    DLLInfo.class, DotSymbol.class,
+                    NativeRawArray.class, NativeCharArray.class, NativeIntegerArray.class,
+                    NativeDoubleArray.class, NativeLogicalArray.class,
+                    RDouble.class, RInteger.class};
 
     private static final class ForeignAccessState {
 
@@ -211,6 +216,20 @@ public final class RForeignAccessFactoryImpl implements RForeignAccessFactory {
                 foreignAccess = RExternalPtrMRForeign.createAccess();
             } else if (RUnboundValue.class.isAssignableFrom(clazz)) {
                 foreignAccess = RUnboundValueMRForeign.createAccess();
+            } else if (NativeRawArray.class.isAssignableFrom(clazz)) {
+                foreignAccess = NativeRawArrayMRForeign.createAccess();
+            } else if (NativeLogicalArray.class.isAssignableFrom(clazz)) {
+                foreignAccess = NativeLogicalArrayMRForeign.createAccess();
+            } else if (NativeCharArray.class.isAssignableFrom(clazz)) {
+                foreignAccess = NativeCharArrayMRForeign.createAccess();
+            } else if (NativeDoubleArray.class.isAssignableFrom(clazz)) {
+                foreignAccess = NativeDoubleArrayMRForeign.createAccess();
+            } else if (NativeIntegerArray.class.isAssignableFrom(clazz)) {
+                foreignAccess = NativeIntegerArrayMRForeign.createAccess();
+            } else if (RInteger.class.isAssignableFrom(clazz)) {
+                foreignAccess = RIntegerMRForeign.createAccess();
+            } else if (RDouble.class.isAssignableFrom(clazz)) {
+                foreignAccess = RDoubleMRForeign.createAccess();
             } else {
                 if (RAbstractVector.class.isAssignableFrom(clazz)) {
                     foreignAccess = ForeignAccess.create(RAbstractVector.class, new RAbstractVectorAccessFactory());
diff --git a/com.oracle.truffle.r.engine/src/com/oracle/truffle/r/engine/interop/RIntegerMR.java b/com.oracle.truffle.r.engine/src/com/oracle/truffle/r/engine/interop/RIntegerMR.java
new file mode 100644
index 0000000000000000000000000000000000000000..94d2c602606c42318d4474d8efa00f8d14594c2e
--- /dev/null
+++ b/com.oracle.truffle.r.engine/src/com/oracle/truffle/r/engine/interop/RIntegerMR.java
@@ -0,0 +1,71 @@
+/*
+ * Copyright (c) 2016, 2016, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package com.oracle.truffle.r.engine.interop;
+
+import com.oracle.truffle.api.interop.CanResolve;
+import com.oracle.truffle.api.interop.MessageResolution;
+import com.oracle.truffle.api.interop.Resolve;
+import com.oracle.truffle.api.interop.TruffleObject;
+import com.oracle.truffle.api.nodes.Node;
+import com.oracle.truffle.r.engine.TruffleRLanguage;
+import com.oracle.truffle.r.runtime.data.RInteger;
+
+@MessageResolution(receiverType = RInteger.class, language = TruffleRLanguage.class)
+public class RIntegerMR {
+    @Resolve(message = "IS_BOXED")
+    public abstract static class RIntegerIsBoxedNode extends Node {
+        protected Object access(@SuppressWarnings("unused") RInteger receiver) {
+            return true;
+        }
+    }
+
+    @Resolve(message = "HAS_SIZE")
+    public abstract static class RIntegerHasSizeNode extends Node {
+        protected Object access(@SuppressWarnings("unused") RInteger receiver) {
+            return false;
+        }
+    }
+
+    @Resolve(message = "IS_NULL")
+    public abstract static class RIntegerIsNullNode extends Node {
+        protected Object access(@SuppressWarnings("unused") RInteger receiver) {
+            return false;
+        }
+    }
+
+    @Resolve(message = "UNBOX")
+    public abstract static class RIntegerUnboxNode extends Node {
+        protected double access(RInteger receiver) {
+            return receiver.getValue();
+        }
+    }
+
+    @CanResolve
+    public abstract static class RIntegerCheck extends Node {
+
+        protected static boolean test(TruffleObject receiver) {
+            return receiver instanceof RInteger;
+        }
+    }
+
+}
diff --git a/com.oracle.truffle.r.engine/src/com/oracle/truffle/r/engine/interop/UnsafeAdapter.java b/com.oracle.truffle.r.engine/src/com/oracle/truffle/r/engine/interop/UnsafeAdapter.java
new file mode 100644
index 0000000000000000000000000000000000000000..e80c125a9fe68c1cb1d8bc11f799d19549d85021
--- /dev/null
+++ b/com.oracle.truffle.r.engine/src/com/oracle/truffle/r/engine/interop/UnsafeAdapter.java
@@ -0,0 +1,46 @@
+/*
+ * Copyright (c) 2014, 2016, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package com.oracle.truffle.r.engine.interop;
+
+import java.lang.reflect.Field;
+
+import sun.misc.Unsafe;
+
+class UnsafeAdapter {
+    static final Unsafe UNSAFE = initUnsafe();
+
+    private static Unsafe initUnsafe() {
+        try {
+            return Unsafe.getUnsafe();
+        } catch (SecurityException se) {
+            try {
+                Field theUnsafe = Unsafe.class.getDeclaredField("theUnsafe");
+                theUnsafe.setAccessible(true);
+                return (Unsafe) theUnsafe.get(Unsafe.class);
+            } catch (Exception e) {
+                throw new RuntimeException("exception while trying to get Unsafe", e);
+            }
+        }
+    }
+
+}
diff --git a/com.oracle.truffle.r.engine/src/com/oracle/truffle/r/engine/interop/ffi/TruffleC.java b/com.oracle.truffle.r.engine/src/com/oracle/truffle/r/engine/interop/ffi/TruffleC.java
new file mode 100644
index 0000000000000000000000000000000000000000..c37ecfff0f865de02e865b69f8ab8fddfe39b2d1
--- /dev/null
+++ b/com.oracle.truffle.r.engine/src/com/oracle/truffle/r/engine/interop/ffi/TruffleC.java
@@ -0,0 +1,83 @@
+/*
+ * Copyright (c) 2014, 2016, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package com.oracle.truffle.r.engine.interop.ffi;
+
+import com.oracle.truffle.api.frame.VirtualFrame;
+import com.oracle.truffle.api.interop.ForeignAccess;
+import com.oracle.truffle.api.interop.Message;
+import com.oracle.truffle.api.nodes.Node;
+import com.oracle.truffle.r.engine.interop.NativeRawArray;
+import com.oracle.truffle.r.engine.interop.NativeDoubleArray;
+import com.oracle.truffle.r.engine.interop.NativeIntegerArray;
+import com.oracle.truffle.r.runtime.RInternalError;
+import com.oracle.truffle.r.runtime.ffi.CRFFI;
+import com.oracle.truffle.r.runtime.ffi.NativeCallInfo;
+import com.oracle.truffle.r.runtime.ffi.jni.JNI_C;
+import com.oracle.truffle.r.runtime.ffi.truffle.TruffleRFFIFrameHelper;
+
+class TruffleC implements CRFFI {
+    private static class TruffleCRFFINode extends JNI_C.JNI_CRFFINode {
+
+        @Override
+        public synchronized void invoke(NativeCallInfo nativeCallInfo, Object[] args) {
+            if (nativeCallInfo.address.value instanceof Long) {
+                super.invoke(nativeCallInfo, args);
+            } else {
+                VirtualFrame frame = TruffleRFFIFrameHelper.create();
+                TruffleDLL.ensureParsed(nativeCallInfo);
+                Object[] wargs = wrap(args);
+                try {
+                    Node messageNode = Message.createExecute(0).createNode();
+                    ForeignAccess.sendExecute(messageNode, frame, nativeCallInfo.address.asTruffleObject(), wargs);
+                } catch (Throwable t) {
+                    throw RInternalError.shouldNotReachHere(t);
+                }
+            }
+        }
+
+        Object[] wrap(Object[] args) {
+            Object[] nargs = new Object[args.length];
+            for (int i = 0; i < args.length; i++) {
+                Object arg = args[i];
+                Object narg;
+                if (arg instanceof int[]) {
+                    narg = new NativeIntegerArray((int[]) arg);
+                } else if (arg instanceof double[]) {
+                    narg = new NativeDoubleArray((double[]) arg);
+                } else if (arg instanceof byte[]) {
+                    narg = new NativeRawArray((byte[]) arg);
+                } else {
+                    throw RInternalError.unimplemented(".C type: " + arg.getClass().getSimpleName());
+                }
+                nargs[i] = narg;
+            }
+            return nargs;
+        }
+    }
+
+    @Override
+    public CRFFINode createCRFFINode() {
+        return new TruffleCRFFINode();
+    }
+
+}
diff --git a/com.oracle.truffle.r.engine/src/com/oracle/truffle/r/engine/interop/ffi/TruffleCAccess.java b/com.oracle.truffle.r.engine/src/com/oracle/truffle/r/engine/interop/ffi/TruffleCAccess.java
new file mode 100644
index 0000000000000000000000000000000000000000..a835741a541a4c3f326358a4fff502f2d54ab9e4
--- /dev/null
+++ b/com.oracle.truffle.r.engine/src/com/oracle/truffle/r/engine/interop/ffi/TruffleCAccess.java
@@ -0,0 +1,54 @@
+/*
+ * Copyright (c) 2016, 2016, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package com.oracle.truffle.r.engine.interop.ffi;
+
+import com.oracle.truffle.r.runtime.ffi.DLL;
+import com.oracle.truffle.r.runtime.ffi.RFFIFactory;
+
+/**
+ * Access to primitive C operations.
+ */
+public class TruffleCAccess {
+    private static final TruffleDLL.TruffleHandle handle = new TruffleDLL.TruffleHandle("libR");
+
+    public enum Function {
+        READ_POINTER_INT,
+        READ_ARRAY_INT,
+        READ_POINTER_DOUBLE,
+        READ_ARRAY_DOUBLE;
+
+        private DLL.SymbolHandle symbolHandle;
+
+        public DLL.SymbolHandle getSymbolHandle() {
+            if (symbolHandle == null) {
+                symbolHandle = RFFIFactory.getRFFI().getDLLRFFI().dlsym(handle, cName());
+            }
+            return symbolHandle;
+        }
+
+        public String cName() {
+            return "caccess_" + name().toLowerCase();
+        }
+    }
+
+}
diff --git a/com.oracle.truffle.r.engine/src/com/oracle/truffle/r/engine/interop/ffi/TruffleCall.java b/com.oracle.truffle.r.engine/src/com/oracle/truffle/r/engine/interop/ffi/TruffleCall.java
new file mode 100644
index 0000000000000000000000000000000000000000..bd2cf5c8099cffd999117f67b117025f6f845bb6
--- /dev/null
+++ b/com.oracle.truffle.r.engine/src/com/oracle/truffle/r/engine/interop/ffi/TruffleCall.java
@@ -0,0 +1,265 @@
+/*
+ * Copyright (c) 2014, 2016, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package com.oracle.truffle.r.engine.interop.ffi;
+
+import com.oracle.truffle.api.dsl.Cached;
+import com.oracle.truffle.api.dsl.ImportStatic;
+import com.oracle.truffle.api.dsl.Specialization;
+import com.oracle.truffle.api.frame.VirtualFrame;
+import com.oracle.truffle.api.interop.ForeignAccess;
+import com.oracle.truffle.api.interop.Message;
+import com.oracle.truffle.api.interop.TruffleObject;
+import com.oracle.truffle.api.interop.java.JavaInterop;
+import com.oracle.truffle.api.nodes.Node;
+import com.oracle.truffle.r.engine.interop.ffi.TruffleCallFactory.InvokeTruffleNodeGen;
+import com.oracle.truffle.r.engine.interop.ffi.TruffleCallFactory.SplitTruffleCallRFFINodeGen;
+import com.oracle.truffle.r.runtime.RInternalError;
+import com.oracle.truffle.r.runtime.context.RContext;
+import com.oracle.truffle.r.runtime.context.RContext.ContextState;
+import com.oracle.truffle.r.runtime.data.RNull;
+import com.oracle.truffle.r.runtime.ffi.CallRFFI;
+import com.oracle.truffle.r.runtime.ffi.NativeCallInfo;
+import com.oracle.truffle.r.runtime.ffi.RFFIVariables;
+import com.oracle.truffle.r.runtime.ffi.DLL.SymbolHandle;
+import com.oracle.truffle.r.runtime.ffi.jni.JNI_Call;
+import com.oracle.truffle.r.runtime.ffi.jni.JNI_Call.JNI_CallRFFINode;
+import com.oracle.truffle.r.runtime.ffi.truffle.TruffleRFFIFrameHelper;
+
+class TruffleCall implements CallRFFI {
+    private static TruffleCall truffleCall;
+    private static TruffleObject truffleCallTruffleObject;
+    private static TruffleObject truffleCallHelper;
+
+    @SuppressWarnings("unused")
+    TruffleCall() {
+        new JNI_Call();
+        truffleCall = this;
+        truffleCallTruffleObject = JavaInterop.asTruffleObject(truffleCall);
+        TrufflePkgInit.initialize();
+        truffleCallHelper = TruffleCallHelper.initialize();
+    }
+
+    static class ContextStateImpl implements RContext.ContextState {
+        private RContext context;
+        private boolean initVariablesDone;
+
+        @Override
+        public ContextState initialize(RContext contextA) {
+            this.context = contextA;
+            context.addExportedSymbol("_fastr_rffi_call", truffleCallTruffleObject);
+            context.addExportedSymbol("_fastr_rffi_callhelper", truffleCallHelper);
+            return this;
+        }
+
+        @Override
+        public void beforeDestroy(RContext contextA) {
+        }
+
+    }
+
+    static ContextStateImpl newContextState() {
+        return new ContextStateImpl();
+    }
+
+    private enum INIT_VAR_FUN {
+        OBJ,
+        DOUBLE,
+        INT;
+
+        private final String funName;
+        private SymbolHandle symbolHandle;
+
+        INIT_VAR_FUN() {
+            funName = "Call_initvar_" + name().toLowerCase();
+        }
+    }
+
+    private static void initVariables(RContext context) {
+        // must have parsed the variables module in libR
+        for (INIT_VAR_FUN initVarFun : INIT_VAR_FUN.values()) {
+            TruffleDLL.ensureParsed("libR", initVarFun.funName, true);
+            initVarFun.symbolHandle = new SymbolHandle(context.getEnv().importSymbol("@" + initVarFun.funName));
+        }
+        VirtualFrame frame = TruffleRFFIFrameHelper.create();
+        Node executeNode = Message.createExecute(2).createNode();
+        RFFIVariables[] variables = RFFIVariables.values();
+        for (int i = 0; i < variables.length; i++) {
+            RFFIVariables var = variables[i];
+            Object value = var.getValue();
+            if (value == null) {
+                continue;
+            }
+            try {
+                if (value instanceof Double) {
+                    ForeignAccess.sendExecute(executeNode, frame, INIT_VAR_FUN.DOUBLE.symbolHandle.asTruffleObject(), i, value);
+                } else if (value instanceof Integer) {
+                    ForeignAccess.sendExecute(executeNode, frame, INIT_VAR_FUN.INT.symbolHandle.asTruffleObject(), i, value);
+                } else {
+                    // TODO
+                    // ForeignAccess.sendExecute(executeNode, frame,
+                    // INIT_VAR_FUN.OBJ.symbolHandle.asTruffleObject(), i, value);
+                }
+            } catch (Throwable t) {
+                throw RInternalError.shouldNotReachHere(t);
+            }
+        }
+    }
+
+    public static class InvokeJNI extends Node {
+        @Child JNI_CallRFFINode jniCall = new JNI_CallRFFINode();
+
+        public Object invokeCall(NativeCallInfo nativeCallInfo, Object[] args) {
+            return jniCall.invokeCall(nativeCallInfo, args);
+        }
+
+        public Object invokeVoidCall(NativeCallInfo nativeCallInfo, Object[] args) {
+            jniCall.invokeVoidCall(nativeCallInfo, args);
+            return RNull.instance;
+        }
+
+    }
+
+    /**
+     * Experimentally the node created for the message send contains cached information regarding
+     * the target, which is {@link RContext} specific, leading to invalid data being accessed in
+     * SHARED_PARENT_RW contexts (specifically the cached exported symbols used for package
+     * initialization). So we guard the node with a check that the context has not changed.
+     *
+     */
+    @ImportStatic({Message.class, RContext.class})
+    public abstract static class InvokeTruffle extends Node {
+        public abstract Object execute(NativeCallInfo nativeCallInfo, Object[] args, RContext context);
+
+        @Specialization(guards = {"context == cachedContext"})
+        protected Object invokeCallCached(NativeCallInfo nativeCallInfo, Object[] args, @SuppressWarnings("unused") RContext context, //
+                        @SuppressWarnings("unused") @Cached("getInstance()") RContext cachedContext,
+                        @Cached("createExecute(0).createNode()") Node messageNode,
+                        @SuppressWarnings("unused") @Cached("ensureReady(nativeCallInfo)") boolean ready) {
+            return doInvoke(messageNode, nativeCallInfo, args);
+        }
+
+        @Specialization(contains = "invokeCallCached")
+        protected Object invokeCallNormal(NativeCallInfo nativeCallInfo, Object[] args, @SuppressWarnings("unused") RContext context) {
+            return doInvoke(Message.createExecute(0).createNode(), nativeCallInfo, args);
+        }
+
+        private static Object doInvoke(Node messageNode, NativeCallInfo nativeCallInfo, Object[] args) {
+            VirtualFrame frame = TruffleRFFIFrameHelper.create();
+            try {
+                return ForeignAccess.sendExecute(messageNode, frame, nativeCallInfo.address.asTruffleObject(), args);
+            } catch (Throwable t) {
+                throw RInternalError.shouldNotReachHere(t);
+            }
+        }
+
+        public static boolean ensureReady(NativeCallInfo nativeCallInfo) {
+            TruffleDLL.ensureParsed(nativeCallInfo);
+            ContextStateImpl contextState = TruffleRFFIContextState.getContextState().callState;
+            if (!contextState.initVariablesDone) {
+                initVariables(contextState.context);
+                contextState.initVariablesDone = true;
+            }
+            return true;
+        }
+
+        public static InvokeTruffle create() {
+            return InvokeTruffleNodeGen.create();
+        }
+
+    }
+
+    /**
+     * This class exists to separate out the delegated JNI calls from the Truffle calls.
+     */
+    public abstract static class SplitTruffleCallRFFINode extends Node {
+        public abstract Object execute(NativeCallInfo nativeCallInfo, Object[] args, boolean voidCall);
+
+        @Specialization(guards = {"isJNICall(nativeCallInfo)", "!voidCall"})
+        protected Object invokeCall(NativeCallInfo nativeCallInfo, Object[] args, @SuppressWarnings("unused") boolean voidCall, //
+                        @Cached("new()") InvokeJNI invokeJNI) {
+            return invokeJNI.invokeCall(nativeCallInfo, args);
+
+        }
+
+        @Specialization(guards = {"isJNICall(nativeCallInfo)", "voidCall"})
+        protected Object invokeVoidCall(NativeCallInfo nativeCallInfo, Object[] args, @SuppressWarnings("unused") boolean voidCall, //
+                        @Cached("new()") InvokeJNI invokeJNI) {
+            return invokeJNI.invokeVoidCall(nativeCallInfo, args);
+
+        }
+
+        @Specialization(guards = "!isJNICall(nativeCallInfo)")
+        protected Object invokeCall(NativeCallInfo nativeCallInfo, Object[] args, @SuppressWarnings("unused") boolean voidCall, //
+                        @Cached("create()") InvokeTruffle invokeTruffle) {
+            return invokeTruffle.execute(nativeCallInfo, args, RContext.getInstance());
+        }
+
+        public static boolean isJNICall(NativeCallInfo nativeCallInfo) {
+            return nativeCallInfo.address.value instanceof Long;
+        }
+
+    }
+
+    private static class TruffleCallRFFINode extends CallRFFINode {
+        @Child SplitTruffleCallRFFINode splitTruffleCallRFFINode = SplitTruffleCallRFFINodeGen.create();
+
+        @Override
+        public synchronized Object invokeCall(NativeCallInfo nativeCallInfo, Object[] args) {
+            return splitTruffleCallRFFINode.execute(nativeCallInfo, args, false);
+
+        }
+
+        @Override
+        public synchronized void invokeVoidCall(NativeCallInfo nativeCallInfo, Object[] args) {
+            splitTruffleCallRFFINode.execute(nativeCallInfo, args, true);
+        }
+
+        @Override
+        public void setTempDir(String tempDir) {
+            // TODO Truffleize
+            new JNI_CallRFFINode().setTempDir(tempDir);
+        }
+
+        @Override
+        public void setInteractive(boolean interactive) {
+            // TODO Truffleize
+            new JNI_CallRFFINode().setInteractive(interactive);
+        }
+
+    }
+
+    /**
+     * Upcalled from Rinternal et al.
+     *
+     * @param function
+     */
+    public void unimplemented(String function) {
+        throw RInternalError.unimplemented("RFFI function: '" + function + "' not implemented");
+    }
+
+    @Override
+    public CallRFFINode createCallRFFINode() {
+        return new TruffleCallRFFINode();
+    }
+
+}
diff --git a/com.oracle.truffle.r.engine/src/com/oracle/truffle/r/engine/interop/ffi/TruffleCallHelper.java b/com.oracle.truffle.r.engine/src/com/oracle/truffle/r/engine/interop/ffi/TruffleCallHelper.java
new file mode 100644
index 0000000000000000000000000000000000000000..4347e0e1d93e8037e661457abe394ac6e3e48b1d
--- /dev/null
+++ b/com.oracle.truffle.r.engine/src/com/oracle/truffle/r/engine/interop/ffi/TruffleCallHelper.java
@@ -0,0 +1,153 @@
+/*
+ * Copyright (c) 2016, 2016, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package com.oracle.truffle.r.engine.interop.ffi;
+
+import java.nio.charset.StandardCharsets;
+
+import com.oracle.truffle.api.interop.TruffleObject;
+import com.oracle.truffle.api.interop.java.JavaInterop;
+import com.oracle.truffle.r.engine.interop.NativeRawArray;
+import com.oracle.truffle.r.engine.interop.NativeCharArray;
+import com.oracle.truffle.r.engine.interop.NativeDoubleArray;
+import com.oracle.truffle.r.engine.interop.NativeIntegerArray;
+import com.oracle.truffle.r.engine.interop.NativeLogicalArray;
+import com.oracle.truffle.r.runtime.REnvVars;
+import com.oracle.truffle.r.runtime.RInternalError;
+import com.oracle.truffle.r.runtime.context.RContext;
+import com.oracle.truffle.r.runtime.data.RDataFactory;
+import com.oracle.truffle.r.runtime.data.RDouble;
+import com.oracle.truffle.r.runtime.data.RInteger;
+import com.oracle.truffle.r.runtime.data.RLogical;
+import com.oracle.truffle.r.runtime.data.RNull;
+import com.oracle.truffle.r.runtime.data.RScalar;
+import com.oracle.truffle.r.runtime.data.RTypedValue;
+import com.oracle.truffle.r.runtime.data.RUnboundValue;
+import com.oracle.truffle.r.runtime.ffi.CharSXPWrapper;
+import com.oracle.truffle.r.runtime.ffi.JavaUpCallsRFFI;
+
+/**
+ * A wrapper class that can be instantiated and export for method lookup. For now just delegates to
+ * {@link JavaUpCallsRFFI}.
+ *
+ */
+public class TruffleCallHelper extends JavaUpCallsRFFI {
+    private static TruffleCallHelper singleton;
+    private static TruffleObject singletonTruffleObject;
+
+    public static TruffleObject initialize() {
+        if (singleton == null) {
+            singleton = new TruffleCallHelper();
+            singletonTruffleObject = JavaInterop.asTruffleObject(singleton);
+        }
+        return singletonTruffleObject;
+    }
+
+    public Object charSXPToNativeCharArray(Object x) {
+        CharSXPWrapper chars = guaranteeInstanceOf(x, CharSXPWrapper.class);
+        return new NativeCharArray(chars.getContents().getBytes());
+    }
+
+    // Checkstyle: stop method name check
+
+    public Object Rf_mkCharLenCE(Object bytes, int encoding) {
+        if (bytes instanceof NativeCharArray) {
+            return super.Rf_mkCharLenCE(((NativeCharArray) bytes).getBytes(), encoding);
+        } else {
+            throw RInternalError.unimplemented();
+        }
+    }
+
+    public Object Rf_install(Object name) {
+        if (name instanceof NativeCharArray) {
+            return RDataFactory.createSymbolInterned(new String(((NativeCharArray) name).getBytes(), StandardCharsets.UTF_8));
+        } else {
+            throw RInternalError.unimplemented();
+        }
+    }
+
+    @Override
+    public Object RAW(Object x) {
+        byte[] value = (byte[]) super.RAW(x);
+        return new NativeRawArray(value);
+    }
+
+    @Override
+    public Object LOGICAL(Object x) {
+        byte[] value = (byte[]) super.LOGICAL(x);
+        return new NativeLogicalArray(x, value);
+    }
+
+    @Override
+    public Object INTEGER(Object x) {
+        int[] value = (int[]) super.INTEGER(x);
+        return new NativeIntegerArray(x, value);
+    }
+
+    @Override
+    public Object REAL(Object x) {
+        // Special handling in Truffle variant
+        double[] value = (double[]) super.REAL(x);
+        return new NativeDoubleArray(x, value);
+    }
+
+    public Object R_Home() {
+        byte[] sbytes = REnvVars.rHome().getBytes();
+        return new NativeCharArray(sbytes);
+    }
+
+    @Override
+    public Object Rf_findVar(Object symbolArg, Object envArg) {
+        Object v = super.Rf_findVar(symbolArg, envArg);
+        if (v instanceof RTypedValue) {
+            return v;
+        } else {
+            return wrapPrimitive(v);
+        }
+    }
+
+    public Object R_NilValue() {
+        return RNull.instance;
+    }
+
+    public Object R_UnboundValue() {
+        return RUnboundValue.instance;
+    }
+
+    public Object bytesToNativeCharArray(byte[] bytes) {
+        return new NativeCharArray(bytes);
+    }
+
+    private static RScalar wrapPrimitive(Object x) {
+        if (x instanceof Double) {
+            return RDouble.valueOf((double) x);
+        } else if (x instanceof Integer) {
+            return RInteger.valueOf((int) x);
+        } else if (x instanceof Byte) {
+            return RLogical.valueOf((byte) x);
+        } else {
+            throw RInternalError.shouldNotReachHere();
+        }
+
+    }
+
+}
diff --git a/com.oracle.truffle.r.engine/src/com/oracle/truffle/r/engine/interop/ffi/TruffleDLL.java b/com.oracle.truffle.r.engine/src/com/oracle/truffle/r/engine/interop/ffi/TruffleDLL.java
new file mode 100644
index 0000000000000000000000000000000000000000..68255337206f51fe889be8627716ac9502c0bd4c
--- /dev/null
+++ b/com.oracle.truffle.r.engine/src/com/oracle/truffle/r/engine/interop/ffi/TruffleDLL.java
@@ -0,0 +1,350 @@
+/*
+ * Copyright (c) 2016, 2016, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package com.oracle.truffle.r.engine.interop.ffi;
+
+import java.nio.file.FileSystems;
+import java.util.HashMap;
+import java.util.Map;
+
+import com.oracle.truffle.api.CallTarget;
+import com.oracle.truffle.api.CompilerAsserts;
+import com.oracle.truffle.api.CompilerDirectives.TruffleBoundary;
+import com.oracle.truffle.api.source.Source;
+import com.oracle.truffle.r.runtime.RInternalError;
+import com.oracle.truffle.r.runtime.Utils;
+import com.oracle.truffle.r.runtime.context.RContext;
+import com.oracle.truffle.r.runtime.context.RContext.ContextState;
+import com.oracle.truffle.r.runtime.ffi.DLL;
+import com.oracle.truffle.r.runtime.ffi.DLL.SymbolHandle;
+import com.oracle.truffle.r.runtime.ffi.jni.JNI_DLL;
+import com.oracle.truffle.r.runtime.ffi.truffle.LLVM_IR;
+import com.oracle.truffle.r.runtime.ffi.DLLRFFI;
+import com.oracle.truffle.r.runtime.ffi.NativeCallInfo;
+
+/**
+ * The Truffle version of {@link DLLRFFI}. {@link TruffleDLL#dlopen} expects to find the LLVM IR
+ * embedded in the shared library. If it exists it is used, unless the library is blacklisted.
+ * Otherwise we fall back to the standard JNI implementation.
+ *
+ * The LLVM bitcode is stored (opaquely) in the shared library file, and access through the
+ * {@link LLVM_IR} class. The {@link LLVM_IR#getLLVMIR(String)} method will return an array of
+ * {@link LLVM_IR} instances for all the modules in the library. These have to be parsed by the
+ * Truffle LLVM system (into ASTs) before they can be interpreted/compiled. Note that there is no
+ * support in Truffle LLVM itself for resolving references to functions in other LLVM modules. If
+ * the function as an LLVM AST cannot be found it is assumed to be a native function. The upshot of
+ * this is that, naively, every module in a library has to be parsed before any modules can be
+ * executed, and inter-library dependencies also have to be handled explicitly. Most of the
+ * inter-library references are to "libR", which is handled specially. If parsing was fast eager
+ * parsing of all modules would not be an issue but, currently, is it not fast and some modules
+ * exhibit pathologies that can take as long as a minute to parse, so some effort to support lazy
+ * parsing has been implemented. Unfortunately this requires additional metadata. Note also that
+ * only functions that are invoked explicitly through on of the RFFI interfaces can be handled
+ * lazily; any internal calls must already be resolved (this would change if LLVM had the callback
+ * facility alluded to above).
+ *
+ * This code can operate with lazy or eager parsing, but additional metadata has to be provided on
+ * the defined/undefined symbols in a module.
+ *
+ * There is one major difference between native and LLVM libraries. There is a single global
+ * instance of a native library and the symbols are, therefore, accessible from any {@link RContext}
+ * instance . However, the (Truffle) function descriptors for an LLVM library are specific to the
+ * {@link RContext} they are created (parsed) in. This has two important consequences:
+ * <ol>
+ * <li>It is theoretically possible to have different versions of libraries in different contexts.
+ * </li>
+ * <li>The {@code libR} library function descriptors must be made available in every context. At the
+ * present time this can only be done by re-parsing the library contents.</li>
+ * </ol>
+ *
+ * Note also that {@code libR} is the only library that is opened in native and LLVM mode, as the
+ * native code is used by non-LLVM packages (libraries) and the LLVM code is used by the LLVM
+ * packages (libraries).
+ */
+class TruffleDLL extends JNI_DLL implements DLLRFFI {
+    /**
+     * Supports lazy parsing of LLVM modules.
+     */
+    static class ParseStatus {
+        /**
+         * Name of associated library.
+         */
+        final String libName;
+        /**
+         * The LLVM IR (bitcode).
+         */
+        final LLVM_IR ir;
+        /**
+         * {@code true} iff the bitcode has been parsed into a Truffle AST.
+         */
+        boolean parsed;
+
+        ParseStatus(String libName, LLVM_IR ir, boolean parsed) {
+            this.libName = libName;
+            this.ir = ir;
+            this.parsed = parsed;
+        }
+
+        @Override
+        public String toString() {
+            CompilerAsserts.neverPartOfCompilation();
+            return String.format("lib %s, module %s, parsed %b%n", libName, ir.name, parsed);
+        }
+    }
+
+    class ContextStateImpl implements RContext.ContextState {
+        /**
+         * A map from function name to its {@link ParseStatus}, allowing fast determination whether
+         * parsing is required in a call, see {@link #ensureParsed}. N.B. parsing happens at the
+         * module level, so all exported functions in one module share the same {@link ParseStatus}
+         * instance.
+         */
+        Map<String, ParseStatus> parseStatusMap = new HashMap<>();
+
+        /**
+         * When a new {@link RContext} is created we have to re-parse the libR modules,
+         * unfortunately, as there is no way to propagate the LLVM state created in the initial
+         * context. TODO when do we really need to do this? This is certainly too early for contexts
+         * that will not invoke LLVM code (e.g. most unit tests)
+         */
+        @Override
+        public ContextState initialize(RContext context) {
+            for (LLVM_IR ir : libRModules) {
+                addExportsToMap(this, "libR", ir, (name) -> name.endsWith("_llvm"));
+            }
+            return this;
+        }
+
+        @Override
+        public void beforeDestroy(RContext context) {
+            if (!context.isInitial()) {
+                parseStatusMap = null;
+            }
+        }
+
+    }
+
+    private static TruffleDLL truffleDLL;
+
+    TruffleDLL() {
+        assert truffleDLL == null;
+        truffleDLL = this;
+    }
+
+    static TruffleDLL getInstance() {
+        assert truffleDLL != null;
+        return truffleDLL;
+    }
+
+    static ContextStateImpl newContextState() {
+        return truffleDLL.new ContextStateImpl();
+    }
+
+    static boolean isBlacklisted(String libName) {
+        String libs = System.getenv("FASTR_TRUFFLE_LIBS");
+        if (libs == null) {
+            Utils.warn(String.format("TruffleDLL: %s, FASTR_TRUFFLE_LIBS is unset, defaulting to JNI", libName));
+            return true;
+        }
+        String[] libsElems = libs.split(",");
+        for (String libsElem : libsElems) {
+            if (libName.equals(libsElem)) {
+                return false;
+            }
+        }
+        return true;
+    }
+
+    static class TruffleHandle {
+        private final String libName;
+
+        TruffleHandle(String libName) {
+            this.libName = libName;
+        }
+    }
+
+    @FunctionalInterface
+    interface ModuleNameMatch {
+        boolean match(String name);
+    }
+
+    /**
+     * If a library is enabled for LLVM,the IR for all the modules is retrieved and analyzed. Every
+     * exported symbol in the module added to the parseStatus map for the current {@link RContext}.
+     * This allows {@link #dlsym} to definitively locate any symbol, even if the IR has not been
+     * parsed yet.
+     */
+    @Override
+    public Object dlopen(String path, boolean local, boolean now) {
+        try {
+            LLVM_IR[] irs = LLVM_IR.getLLVMIR(path);
+            String libName = getLibName(path);
+            // even if libR is not all LLVM executed, some parts have to be
+            // but they can't be parsed now
+            if (libName.equals("libR")) {
+                libRModules = irs;
+            }
+            if (irs == null || isBlacklisted(libName)) {
+                return super.dlopen(path, local, now);
+            } else {
+                ContextStateImpl contextState = getContextState();
+                for (int i = 0; i < irs.length; i++) {
+                    LLVM_IR ir = irs[i];
+                    addExportsToMap(contextState, libName, ir, (name) -> true);
+                }
+                return new TruffleHandle(libName);
+            }
+        } catch (Exception ex) {
+            return null;
+        }
+    }
+
+    private static void addExportsToMap(ContextStateImpl contextState, String libName, LLVM_IR ir, ModuleNameMatch moduleNameMatch) {
+        ParseStatus parseStatus = new ParseStatus(libName, ir, false);
+        for (String export : ir.exports) {
+            if (moduleNameMatch.match(ir.name)) {
+                assert contextState.parseStatusMap.get(export) == null;
+                contextState.parseStatusMap.put(export, parseStatus);
+            }
+        }
+    }
+
+    private static String getLibName(String path) {
+        String fileName = FileSystems.getDefault().getPath(path).getFileName().toString();
+        int ix = fileName.lastIndexOf(".");
+        return fileName.substring(0, ix);
+    }
+
+    /**
+     * Record of the libR modules for subsequent parsing.
+     */
+    private LLVM_IR[] libRModules;
+
+    private static ContextStateImpl getContextState() {
+        return TruffleRFFIContextState.getContextState().dllState;
+    }
+
+    /**
+     * About to invoke the (external) function denoted by {@code nativeCallInfo}. Therefore, it must
+     * have been parsed (in {@link #dlsym(Object, String)}) AND all dependent modules, recursively,
+     * must also be parsed. Evidently since the dependencies are expressed at a module level, this
+     * may parse more than strictly necessary.
+     *
+     * @param nativeCallInfo
+     */
+    static void ensureParsed(NativeCallInfo nativeCallInfo) {
+        ensureParsed(nativeCallInfo.dllInfo.name, nativeCallInfo.name, true);
+    }
+
+    /**
+     * Similar to {@link #ensureParsed(NativeCallInfo)} but with a function specified as a string
+     * (for internal use) and an optional check whether the function must exist.
+     *
+     * @param libName TODO
+     */
+    @TruffleBoundary
+    static void ensureParsed(String libName, String name, boolean fatalIfMissing) {
+        ContextStateImpl contextState = getContextState();
+        Map<String, ParseStatus> parseStatusMap = contextState.parseStatusMap;
+        ParseStatus parseStatus = parseStatusMap.get(name);
+        assert parseStatus != null || !fatalIfMissing;
+        if (parseStatus != null && !parseStatus.parsed) {
+            parseLLVM(parseStatus.ir);
+            parseStatus.parsed = true;
+            boolean isPackageInit = isPackageInit(libName, name);
+            for (String importee : parseStatus.ir.imports) {
+                /*
+                 * If we are resolving a package init call, we do not want to resolve all the
+                 * imports if functions in the same library as this will cause everything in the
+                 * library to be parsed eagerly!
+                 */
+                ParseStatus importeeParseStatus = parseStatusMap.get(importee);
+                boolean internal = isPackageInit && importeeParseStatus.libName.equals(libName);
+                if (importeeParseStatus != null && !internal) {
+                    ensureParsed(libName, importee, false);
+                }
+            }
+        }
+    }
+
+    private static boolean isPackageInit(@SuppressWarnings("unused") String libName, String name) {
+        if (name.startsWith(DLL.R_INIT_PREFIX)) {
+            return true;
+        } else {
+            return false;
+        }
+    }
+
+    private static void parseLLVM(LLVM_IR ir) {
+        if (ir instanceof LLVM_IR.Binary) {
+            LLVM_IR.Binary bir = (LLVM_IR.Binary) ir;
+            parseBinary(bir);
+        } else {
+            throw RInternalError.unimplemented("LLVM text IR");
+        }
+    }
+
+    private static CallTarget parseBinary(LLVM_IR.Binary ir) {
+        long start = System.nanoTime();
+        RContext context = RContext.getInstance();
+        long nanos = 1000 * 1000 * 1000;
+        Source source = Source.newBuilder(ir.base64).name(ir.name).mimeType("application/x-llvm-ir-bitcode-base64").build();
+        CallTarget result = context.getEnv().parse(source);
+        if (System.getenv("LLVM_PARSE_TIME") != null) {
+            long end = System.nanoTime();
+            System.out.printf("parsed %s in %f secs%n", ir.name, ((double) (end - start)) / (double) nanos);
+        }
+        return result;
+    }
+
+    @Override
+    public SymbolHandle dlsym(Object handle, String symbol) {
+        if (handle instanceof TruffleHandle) {
+            // If the symbol exists it will be in the map
+            ParseStatus parseStatus = getContextState().parseStatusMap.get(symbol);
+            if (parseStatus != null && parseStatus.libName.equals(((TruffleHandle) handle).libName)) {
+                // force a parse so we have a "value"
+                if (!parseStatus.parsed) {
+                    ensureParsed(parseStatus.libName, symbol, true);
+                }
+                Object symValue = RContext.getInstance().getEnv().importSymbol("@" + symbol);
+                assert symValue != null;
+                return new SymbolHandle(symValue);
+            } else {
+                // symbol not found (or not in requested library)
+                return null;
+            }
+        } else {
+            return super.dlsym(handle, symbol);
+        }
+    }
+
+    @Override
+    public int dlclose(Object handle) {
+        if (handle instanceof TruffleHandle) {
+            return 0;
+        } else {
+            return super.dlclose(handle);
+        }
+    }
+
+}
diff --git a/com.oracle.truffle.r.engine/src/com/oracle/truffle/r/engine/interop/ffi/TrufflePkgInit.java b/com.oracle.truffle.r.engine/src/com/oracle/truffle/r/engine/interop/ffi/TrufflePkgInit.java
new file mode 100644
index 0000000000000000000000000000000000000000..c73897234ac24c90c3f35384dd688bd6a88d50ac
--- /dev/null
+++ b/com.oracle.truffle.r.engine/src/com/oracle/truffle/r/engine/interop/ffi/TrufflePkgInit.java
@@ -0,0 +1,119 @@
+/*
+ * Copyright (c) 2014, 2016, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package com.oracle.truffle.r.engine.interop.ffi;
+
+import com.oracle.truffle.api.frame.VirtualFrame;
+import com.oracle.truffle.api.interop.ForeignAccess;
+import com.oracle.truffle.api.interop.Message;
+import com.oracle.truffle.api.interop.TruffleObject;
+import com.oracle.truffle.api.interop.java.JavaInterop;
+import com.oracle.truffle.api.nodes.Node;
+import com.oracle.truffle.r.runtime.RInternalError;
+import com.oracle.truffle.r.runtime.context.RContext;
+import com.oracle.truffle.r.runtime.context.RContext.ContextState;
+import com.oracle.truffle.r.runtime.ffi.DLL;
+import com.oracle.truffle.r.runtime.ffi.DLL.DLLInfo;
+import com.oracle.truffle.r.runtime.ffi.DLL.DotSymbol;
+import com.oracle.truffle.r.runtime.ffi.DLL.SymbolHandle;
+import com.oracle.truffle.r.runtime.ffi.truffle.TruffleRFFIFrameHelper;
+
+class TrufflePkgInit {
+
+    private static TrufflePkgInit trufflePkgInit;
+    private static TruffleObject trufflePkgInitTruffleObject;
+
+    static class ContextStateImpl implements RContext.ContextState {
+        @Override
+        public ContextState initialize(RContext context) {
+            context.addExportedSymbol("_fastr_rffi_pkginit", trufflePkgInitTruffleObject);
+            return this;
+        }
+
+        @Override
+        public void beforeDestroy(RContext context) {
+        }
+    }
+
+    static ContextStateImpl newContextState() {
+        return new ContextStateImpl();
+    }
+
+    static TrufflePkgInit initialize() {
+        if (trufflePkgInit == null) {
+            trufflePkgInit = new TrufflePkgInit();
+            trufflePkgInitTruffleObject = JavaInterop.asTruffleObject(trufflePkgInit);
+        }
+        return trufflePkgInit;
+    }
+
+    public void registerRoutines(DLLInfo dllInfo, int nstOrd, int num, long routines) {
+        DotSymbol[] array = new DotSymbol[num];
+        SymbolHandle setSymbolHandle = new SymbolHandle(RContext.getInstance().getEnv().importSymbol("@" + "PkgInit_setSymbol"));
+        for (int i = 0; i < num; i++) {
+            Object sym = setSymbol(nstOrd, routines, i, setSymbolHandle);
+            array[i] = (DotSymbol) sym;
+        }
+        dllInfo.setNativeSymbols(nstOrd, array);
+    }
+
+    private static Object setSymbol(int nstOrd, long routines, int index, SymbolHandle symbolHandle) {
+        VirtualFrame frame = TruffleRFFIFrameHelper.create();
+        Node executeNode = Message.createExecute(3).createNode();
+        try {
+
+            Object result = ForeignAccess.sendExecute(executeNode, frame, symbolHandle.asTruffleObject(), nstOrd, routines, index);
+            return result;
+        } catch (Throwable t) {
+            throw RInternalError.shouldNotReachHere();
+        }
+
+    }
+
+    @SuppressWarnings("unused")
+    public void registerCCallable(String pkgName, String functionName, long address) {
+        // TBD
+        System.console();
+    }
+
+    @SuppressWarnings({"unused", "static-method"})
+    private long getCCallable(String pkgName, String functionName) {
+        // TBD
+        throw RInternalError.unimplemented();
+    }
+
+    /**
+     * Upcall from native to create a {@link DotSymbol} value.
+     */
+    public DotSymbol createDotSymbol(String name, Object fundesc, int numArgs) {
+        return new DotSymbol(name, new SymbolHandle(fundesc), numArgs);
+    }
+
+    public int useDynamicSymbols(DLLInfo dllInfo, int value) {
+        return DLL.useDynamicSymbols(dllInfo, value);
+    }
+
+    public int forceSymbols(DLLInfo dllInfo, int value) {
+        return DLL.forceSymbols(dllInfo, value);
+    }
+
+}
diff --git a/com.oracle.truffle.r.engine/src/com/oracle/truffle/r/engine/interop/ffi/TruffleRFFIContextState.java b/com.oracle.truffle.r.engine/src/com/oracle/truffle/r/engine/interop/ffi/TruffleRFFIContextState.java
new file mode 100644
index 0000000000000000000000000000000000000000..bd937ee2872fc4ece8f61621267aa7d1a754dc6f
--- /dev/null
+++ b/com.oracle.truffle.r.engine/src/com/oracle/truffle/r/engine/interop/ffi/TruffleRFFIContextState.java
@@ -0,0 +1,70 @@
+/*
+ * Copyright (c) 2014, 2016, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package com.oracle.truffle.r.engine.interop.ffi;
+
+import com.oracle.truffle.r.runtime.context.RContext;
+import com.oracle.truffle.r.runtime.context.RContext.ContextState;
+
+/**
+ * A facade for the context state for the Truffle LLVM factory. Delegates to the various
+ * module-specific pieces of state. This may get merged into a single instance eventually.
+ */
+class TruffleRFFIContextState implements ContextState {
+    TruffleDLL.ContextStateImpl dllState;
+    TrufflePkgInit.ContextStateImpl pkgInitState;
+    TruffleCall.ContextStateImpl callState;
+    TruffleStats.ContextStateImpl statsState;
+
+    TruffleRFFIContextState() {
+        dllState = TruffleDLL.newContextState();
+        pkgInitState = TrufflePkgInit.newContextState();
+        callState = TruffleCall.newContextState();
+        statsState = TruffleStats.newContextState();
+    }
+
+    static TruffleRFFIContextState getContextState() {
+        return (TruffleRFFIContextState) RContext.getInstance().getStateRFFI();
+    }
+
+    static TruffleRFFIContextState getContextState(RContext context) {
+        return (TruffleRFFIContextState) context.getStateRFFI();
+    }
+
+    @Override
+    public ContextState initialize(RContext context) {
+        dllState.initialize(context);
+        pkgInitState.initialize(context);
+        callState.initialize(context);
+        statsState.initialize(context);
+        return this;
+    }
+
+    @Override
+    public void beforeDestroy(RContext context) {
+        dllState.beforeDestroy(context);
+        pkgInitState.beforeDestroy(context);
+        callState.beforeDestroy(context);
+        statsState.beforeDestroy(context);
+    }
+
+}
diff --git a/com.oracle.truffle.r.engine/src/com/oracle/truffle/r/engine/interop/ffi/TruffleStats.java b/com.oracle.truffle.r.engine/src/com/oracle/truffle/r/engine/interop/ffi/TruffleStats.java
new file mode 100644
index 0000000000000000000000000000000000000000..61e65d2a56178c322cf64254da17893eeb073e72
--- /dev/null
+++ b/com.oracle.truffle.r.engine/src/com/oracle/truffle/r/engine/interop/ffi/TruffleStats.java
@@ -0,0 +1,208 @@
+/*
+ * Copyright (c) 2014, 2016, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package com.oracle.truffle.r.engine.interop.ffi;
+
+import com.oracle.truffle.api.CompilerDirectives.TruffleBoundary;
+import com.oracle.truffle.api.dsl.Cached;
+import com.oracle.truffle.api.dsl.ImportStatic;
+import com.oracle.truffle.api.dsl.Specialization;
+import com.oracle.truffle.api.frame.VirtualFrame;
+import com.oracle.truffle.api.interop.ForeignAccess;
+import com.oracle.truffle.api.interop.Message;
+import com.oracle.truffle.api.nodes.Node;
+import com.oracle.truffle.r.engine.interop.NativeDoubleArray;
+import com.oracle.truffle.r.engine.interop.NativeIntegerArray;
+import com.oracle.truffle.r.engine.interop.ffi.TruffleStatsFactory.ExecuteFactorNodeGen;
+import com.oracle.truffle.r.engine.interop.ffi.TruffleStatsFactory.ExecuteWorkNodeGen;
+import com.oracle.truffle.r.runtime.RInternalError;
+import com.oracle.truffle.r.runtime.context.RContext;
+import com.oracle.truffle.r.runtime.context.RContext.ContextState;
+import com.oracle.truffle.r.runtime.ffi.DLL;
+import com.oracle.truffle.r.runtime.ffi.StatsRFFI;
+import com.oracle.truffle.r.runtime.ffi.DLL.DLLInfo;
+import com.oracle.truffle.r.runtime.ffi.DLL.SymbolHandle;
+import com.oracle.truffle.r.runtime.ffi.truffle.TruffleRFFIFrameHelper;
+
+public class TruffleStats implements StatsRFFI {
+
+    public enum FFT_FUN {
+        fft_work,
+        fft_factor;
+    }
+
+    static class ContextStateImpl implements RContext.ContextState {
+        @Override
+        public ContextState initialize(RContext context) {
+            /*
+             * In the case of a SHARE_PARENT_RW context, there is no dlopen call for stats, so the
+             * fft_work/fft_factor functions will not be added into the context symbol map, so we do
+             * it here.
+             */
+            if (context.getKind() == RContext.ContextKind.SHARE_PARENT_RW) {
+                TruffleDLL.ContextStateImpl contextState = TruffleRFFIContextState.getContextState().dllState;
+                TruffleDLL.ContextStateImpl parentDLLContextState = TruffleRFFIContextState.getContextState(context.getParent()).dllState;
+                TruffleDLL.ParseStatus parseStatus = null;
+                for (FFT_FUN f : FFT_FUN.values()) {
+                    String funName = f.name();
+                    TruffleDLL.ParseStatus parentParseStatus = parentDLLContextState.parseStatusMap.get(funName);
+                    if (parentParseStatus != null) {
+                        if (parseStatus == null) {
+                            parseStatus = new TruffleDLL.ParseStatus("stats", parentParseStatus.ir, false);
+                        }
+                        contextState.parseStatusMap.put(f.name(), parseStatus);
+                    }
+                }
+            }
+            return this;
+        }
+
+        @Override
+        public void beforeDestroy(RContext context) {
+        }
+    }
+
+    static ContextStateImpl newContextState() {
+        return new ContextStateImpl();
+    }
+
+    public abstract static class LookupAdapter extends Node {
+        public SymbolHandle lookup(String name) {
+            DLLInfo dllInfo = DLL.findLibrary("stats");
+            // cannot go through DLL because stats does not allow dynamic lookup
+            // and these symbols are not registered (only fft)
+            SymbolHandle result = TruffleDLL.getInstance().dlsym(dllInfo.handle, name);
+            if (result == DLL.SYMBOL_NOT_FOUND) {
+                @SuppressWarnings("unused")
+                TruffleRFFIContextState cs = TruffleRFFIContextState.getContextState();
+                throw RInternalError.shouldNotReachHere();
+            }
+            return result;
+        }
+    }
+
+    @ImportStatic({RContext.class})
+    public abstract static class ExecuteWork extends LookupAdapter {
+        public abstract int execute(double[] a, int nseg, int n, int nspn, int isn, double[] work, int[] iwork, RContext context);
+
+        @Specialization(guards = "context == cachedContext")
+        protected int executeWorkCached(double[] a, int nseg, int n, int nspn, int isn, double[] work, int[] iwork, @SuppressWarnings("unused") RContext context, //
+                        @SuppressWarnings("unused") @Cached("getInstance()") RContext cachedContext,
+                        @Cached("createMessageNode()") Node messageNode,
+                        @Cached("lookupWork()") SymbolHandle fftWork) {
+            return doWork(a, nseg, n, nspn, isn, work, iwork, messageNode, fftWork);
+        }
+
+        @Specialization(contains = "executeWorkCached")
+        protected int executeWorkNormal(double[] a, int nseg, int n, int nspn, int isn, double[] work, int[] iwork, @SuppressWarnings("unused") RContext context) {
+            return doWork(a, nseg, n, nspn, isn, work, iwork, createMessageNode(), lookup("fft_work"));
+        }
+
+        private static int doWork(double[] a, int nseg, int n, int nspn, int isn, double[] work, int[] iwork, Node messageNode, SymbolHandle fftWork) {
+            NativeDoubleArray na = new NativeDoubleArray(a);
+            NativeDoubleArray nwork = new NativeDoubleArray(work);
+            NativeIntegerArray niwork = new NativeIntegerArray(iwork);
+            VirtualFrame frame = TruffleRFFIFrameHelper.create();
+            try {
+                return (int) ForeignAccess.sendExecute(messageNode, frame, fftWork.asTruffleObject(), na, nseg, n, nspn, isn, nwork, niwork);
+            } catch (Throwable t) {
+                throw RInternalError.shouldNotReachHere(t);
+            }
+        }
+
+        public static Node createMessageNode() {
+            return Message.createExecute(7).createNode();
+        }
+
+        public static ExecuteWork create() {
+            return ExecuteWorkNodeGen.create();
+        }
+
+        public SymbolHandle lookupWork() {
+            return lookup("fft_work");
+        }
+    }
+
+    @ImportStatic({RContext.class})
+    public abstract static class ExecuteFactor extends LookupAdapter {
+        protected abstract void execute(int n, int[] pmaxf, int[] pmaxp, RContext context);
+
+        @Specialization(guards = "context == cachedContext")
+        protected void executeFactorCached(int n, int[] pmaxf, int[] pmaxp, @SuppressWarnings("unused") RContext context, //
+                        @SuppressWarnings("unused") @Cached("getInstance()") RContext cachedContext,
+                        @Cached("createMessageNode()") Node messageNode,
+                        @Cached("lookupFactor()") SymbolHandle fftFactor) {
+            doFactor(n, pmaxf, pmaxp, messageNode, fftFactor);
+        }
+
+        @Specialization(contains = "executeFactorCached")
+        protected void executeFactorNormal(int n, int[] pmaxf, int[] pmaxp, @SuppressWarnings("unused") RContext context) {
+            doFactor(n, pmaxf, pmaxp, createMessageNode(), lookup("fft_factor"));
+        }
+
+        private static void doFactor(int n, int[] pmaxf, int[] pmaxp, Node messageNode, SymbolHandle fftFactor) {
+            NativeIntegerArray npmaxf = new NativeIntegerArray(pmaxf);
+            NativeIntegerArray npmaxp = new NativeIntegerArray(pmaxp);
+            VirtualFrame frame = TruffleRFFIFrameHelper.create();
+
+            try {
+                ForeignAccess.sendExecute(messageNode, frame, fftFactor.asTruffleObject(), n, npmaxf, npmaxp);
+            } catch (Throwable t) {
+                throw RInternalError.shouldNotReachHere(t);
+            }
+        }
+
+        public static Node createMessageNode() {
+            return Message.createExecute(3).createNode();
+        }
+
+        public static ExecuteFactor create() {
+            return ExecuteFactorNodeGen.create();
+        }
+
+        public SymbolHandle lookupFactor() {
+            return lookup("fft_factor");
+        }
+    }
+
+    public static class Truffle_FFTNode extends FFTNode {
+        @Child ExecuteWork executeWork = ExecuteWork.create();
+        @Child ExecuteFactor executeFactor = ExecuteFactor.create();
+
+        @Override
+        public int executeWork(double[] a, int nseg, int n, int nspn, int isn, double[] work, int[] iwork) {
+            return executeWork.execute(a, nseg, n, nspn, isn, work, iwork, RContext.getInstance());
+        }
+
+        @Override
+        public void executeFactor(int n, int[] pmaxf, int[] pmaxp) {
+            executeFactor.execute(n, pmaxf, pmaxp, RContext.getInstance());
+        }
+
+    }
+
+    @Override
+    public FFTNode createFFTNode() {
+        return new Truffle_FFTNode();
+    }
+
+}
diff --git a/com.oracle.truffle.r.engine/src/com/oracle/truffle/r/engine/interop/ffi/TruffleUserRng.java b/com.oracle.truffle.r.engine/src/com/oracle/truffle/r/engine/interop/ffi/TruffleUserRng.java
new file mode 100644
index 0000000000000000000000000000000000000000..2f1ccf7b942503f909037a3a246731d56875a772
--- /dev/null
+++ b/com.oracle.truffle.r.engine/src/com/oracle/truffle/r/engine/interop/ffi/TruffleUserRng.java
@@ -0,0 +1,108 @@
+/*
+ * Copyright (c) 2016, 2016, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package com.oracle.truffle.r.engine.interop.ffi;
+
+import static com.oracle.truffle.r.runtime.rng.user.UserRNG.Function;
+import com.oracle.truffle.api.frame.VirtualFrame;
+import com.oracle.truffle.api.interop.ForeignAccess;
+import com.oracle.truffle.api.interop.Message;
+import com.oracle.truffle.api.nodes.Node;
+import com.oracle.truffle.r.runtime.RInternalError;
+import com.oracle.truffle.r.runtime.ffi.UserRngRFFI;
+import com.oracle.truffle.r.runtime.ffi.truffle.TruffleRFFIFrameHelper;
+
+public class TruffleUserRng implements UserRngRFFI {
+    private static class TruffleUserRngRFFINode extends UserRngRFFINode {
+        Node initMessage;
+        Node randMessage;
+        Node nSeedMessage;
+        Node seedsMessage;
+        Node readPointerNode = Message.createExecute(1).createNode();
+
+        @Override
+        public void init(int seed) {
+            VirtualFrame frame = TruffleRFFIFrameHelper.create();
+            if (initMessage == null) {
+                initMessage = Message.createExecute(1).createNode();
+            }
+            try {
+                ForeignAccess.sendExecute(initMessage, frame, Function.Init.getSymbolHandle().asTruffleObject(), seed);
+            } catch (Throwable t) {
+                throw RInternalError.shouldNotReachHere();
+            }
+        }
+
+        @Override
+        public double rand() {
+            VirtualFrame frame = TruffleRFFIFrameHelper.create();
+            if (randMessage == null) {
+                randMessage = Message.createExecute(0).createNode();
+            }
+            try {
+                Object address = ForeignAccess.sendExecute(randMessage, frame, Function.Rand.getSymbolHandle().asTruffleObject());
+                Object value = ForeignAccess.sendExecute(readPointerNode, frame, TruffleCAccess.Function.READ_POINTER_DOUBLE.getSymbolHandle().asTruffleObject(), address);
+                return (double) value;
+            } catch (Throwable t) {
+                throw RInternalError.shouldNotReachHere();
+            }
+        }
+
+        @Override
+        public int nSeed() {
+            VirtualFrame frame = TruffleRFFIFrameHelper.create();
+            if (nSeedMessage == null) {
+                nSeedMessage = Message.createExecute(0).createNode();
+            }
+            try {
+                Object address = ForeignAccess.sendExecute(nSeedMessage, frame, Function.NSeed.getSymbolHandle().asTruffleObject());
+                Object n = ForeignAccess.sendExecute(readPointerNode, frame, TruffleCAccess.Function.READ_POINTER_INT.getSymbolHandle().asTruffleObject(), address);
+                return (int) n;
+            } catch (Throwable t) {
+                throw RInternalError.shouldNotReachHere();
+            }
+        }
+
+        @Override
+        public void seeds(int[] n) {
+            VirtualFrame frame = TruffleRFFIFrameHelper.create();
+            if (seedsMessage == null) {
+                seedsMessage = Message.createExecute(0).createNode();
+            }
+            try {
+                Object address = ForeignAccess.sendExecute(seedsMessage, frame, Function.Seedloc.getSymbolHandle().asTruffleObject());
+                for (int i = 0; i < n.length; i++) {
+                    Object seed = ForeignAccess.sendExecute(readPointerNode, frame, TruffleCAccess.Function.READ_ARRAY_INT.getSymbolHandle().asTruffleObject(), address, i);
+                    n[i] = (int) seed;
+                }
+            } catch (Throwable t) {
+                throw RInternalError.shouldNotReachHere();
+            }
+        }
+    }
+
+    @Override
+    public UserRngRFFINode createUserRngRFFINode() {
+        return new TruffleUserRngRFFINode();
+    }
+
+}
diff --git a/com.oracle.truffle.r.engine/src/com/oracle/truffle/r/engine/interop/ffi/Truffle_RFFIFactory.java b/com.oracle.truffle.r.engine/src/com/oracle/truffle/r/engine/interop/ffi/Truffle_RFFIFactory.java
new file mode 100644
index 0000000000000000000000000000000000000000..2bf1a5c7f7a0d0fc6dd10a434d9ab320e07e4db7
--- /dev/null
+++ b/com.oracle.truffle.r.engine/src/com/oracle/truffle/r/engine/interop/ffi/Truffle_RFFIFactory.java
@@ -0,0 +1,103 @@
+/*
+ * Copyright (c) 2014, 2016, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package com.oracle.truffle.r.engine.interop.ffi;
+
+import com.oracle.truffle.r.runtime.context.RContext.ContextState;
+import com.oracle.truffle.r.runtime.ffi.CRFFI;
+import com.oracle.truffle.r.runtime.ffi.CallRFFI;
+import com.oracle.truffle.r.runtime.ffi.DLLRFFI;
+import com.oracle.truffle.r.runtime.ffi.RFFI;
+import com.oracle.truffle.r.runtime.ffi.StatsRFFI;
+import com.oracle.truffle.r.runtime.ffi.UserRngRFFI;
+import com.oracle.truffle.r.runtime.ffi.jni.JNI_RFFIFactory;
+
+/**
+ * Incremental approach to using Truffle, defaults to the JNI factory.
+ *
+ */
+public class Truffle_RFFIFactory extends JNI_RFFIFactory implements RFFI {
+
+    @Override
+    protected void initialize(boolean runtime) {
+        super.initialize(runtime);
+    }
+
+    @Override
+    public ContextState newContextState() {
+        return new TruffleRFFIContextState();
+    }
+
+    private CRFFI cRFFI;
+
+    @Override
+    public CRFFI getCRFFI() {
+        if (cRFFI == null) {
+            cRFFI = new TruffleC();
+        }
+        return cRFFI;
+    }
+
+    private DLLRFFI dllRFFI;
+
+    @Override
+    public DLLRFFI getDLLRFFI() {
+        if (dllRFFI == null) {
+            dllRFFI = new TruffleDLL();
+        }
+        return dllRFFI;
+    }
+
+    private UserRngRFFI truffleUserRngRFFI;
+
+    @Override
+    public UserRngRFFI getUserRngRFFI() {
+        if (truffleUserRngRFFI == null) {
+            truffleUserRngRFFI = new TruffleUserRng();
+        }
+        return truffleUserRngRFFI;
+    }
+
+    private CallRFFI truffleCallRFFI;
+
+    @Override
+    public CallRFFI getCallRFFI() {
+        if (truffleCallRFFI == null) {
+            truffleCallRFFI = new TruffleCall();
+        }
+        return truffleCallRFFI;
+    }
+
+    private StatsRFFI truffleStatsRFFI;
+
+    @Override
+    public StatsRFFI getStatsRFFI() {
+        if (TruffleDLL.isBlacklisted("stats")) {
+            return super.getStatsRFFI();
+        }
+        if (truffleStatsRFFI == null) {
+            truffleStatsRFFI = new TruffleStats();
+        }
+        return truffleStatsRFFI;
+    }
+
+}
diff --git a/com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/stats/Cauchy.java b/com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/stats/Cauchy.java
index 3ab4aaf4548915fe6de78d90ce103a82f522d559..dfc539f914efc2ecc2dc7af0524b728edadbe1a6 100644
--- a/com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/stats/Cauchy.java
+++ b/com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/stats/Cauchy.java
@@ -25,11 +25,11 @@ public final class Cauchy {
         // contains only static classes
     }
 
-    public static final class RCauchy implements RandFunction2_Double {
+    public static final class RCauchy extends RandFunction2_Double {
         @Override
-        public double evaluate(double location, double scale, RandomNumberProvider rand) {
+        public double execute(double location, double scale, RandomNumberProvider rand) {
             if (Double.isNaN(location) || !Double.isFinite(scale) || scale < 0) {
-                return RMath.mlError();
+                return RMathError.defaultError();
             }
             if (scale == 0. || !Double.isFinite(location)) {
                 return location;
@@ -48,7 +48,7 @@ public final class Cauchy {
                 return x + location + scale;
             }
             if (scale <= 0) {
-                return RMath.mlError();
+                return RMathError.defaultError();
             }
 
             y = (x - location) / scale;
@@ -64,16 +64,16 @@ public final class Cauchy {
             }
 
             if (scale <= 0) {
-                return RMath.mlError();
+                return RMathError.defaultError();
             }
 
-            x = (x - location) / scale;
-            if (Double.isNaN(x)) {
-                return RMath.mlError();
+            double x2 = (x - location) / scale;
+            if (Double.isNaN(x2)) {
+                return RMathError.defaultError();
             }
 
-            if (!Double.isFinite(x)) {
-                if (x < 0) {
+            if (!Double.isFinite(x2)) {
+                if (x2 < 0) {
                     return DPQ.rdt0(lowerTail, logP);
                 } else {
                     return DPQ.rdt1(lowerTail, logP);
@@ -81,7 +81,7 @@ public final class Cauchy {
             }
 
             if (!lowerTail) {
-                x = -x;
+                x2 = -x2;
             }
 
             /*
@@ -91,18 +91,19 @@ public final class Cauchy {
 
             // GnuR has #ifdef HAVE_ATANPI where it uses atanpi function, here we only implement the
             // case when atanpi is not available for the moment
-            if (fabs(x) > 1) {
-                double y = Math.atan(1 / x) / M_PI;
-                return (x > 0) ? DPQ.rdclog(y, logP) : DPQ.rdval(-y, logP);
+            if (fabs(x2) > 1) {
+                double y = Math.atan(1 / x2) / M_PI;
+                return (x2 > 0) ? DPQ.rdclog(y, logP) : DPQ.rdval(-y, logP);
             } else {
-                return DPQ.rdval(0.5 + Math.atan(x) / M_PI, logP);
+                return DPQ.rdval(0.5 + Math.atan(x2) / M_PI, logP);
             }
         }
     }
 
     public static final class QCauchy implements Function3_2 {
         @Override
-        public double evaluate(double p, double location, double scale, boolean lowerTail, boolean logP) {
+        public double evaluate(double pIn, double location, double scale, boolean lowerTailIn, boolean logP) {
+            double p = pIn;
             if (Double.isNaN(p) || Double.isNaN(location) || Double.isNaN(scale)) {
                 return p + location + scale;
             }
@@ -115,9 +116,10 @@ public final class Cauchy {
                 if (scale == 0) {
                     return location;
                 }
-                return RMath.mlError();
+                return RMathError.defaultError();
             }
 
+            boolean lowerTail = lowerTailIn;
             if (logP) {
                 if (p > -1) {
                     /*
diff --git a/com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/stats/Cdist.java b/com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/stats/Cdist.java
index 9094f3e34ff8d521a8ec586a20f0686e6d561c10..907b465efc254e717a22ada4cbbdff105e511492 100644
--- a/com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/stats/Cdist.java
+++ b/com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/stats/Cdist.java
@@ -12,6 +12,7 @@
  */
 package com.oracle.truffle.r.library.stats;
 
+import static com.oracle.truffle.r.library.stats.MathConstants.DBL_MIN;
 import static com.oracle.truffle.r.nodes.builtin.CastBuilder.Predef.instanceOf;
 
 import com.oracle.truffle.api.dsl.Cached;
@@ -229,7 +230,7 @@ public abstract class Cdist extends RExternalBuiltinNode.Arg4 {
                     if (bothNonNAN(x[i1], x[i2])) {
                         sum = Math.abs(x[i1] + x[i2]);
                         diff = Math.abs(x[i1] - x[i2]);
-                        if (sum > Double.MIN_VALUE || diff > Double.MIN_VALUE) {
+                        if (sum > DBL_MIN || diff > DBL_MIN) {
                             dev = diff / sum;
                             if (!RRuntime.isNAorNaN(dev) ||
                                             (!RRuntime.isFinite(diff) && diff == sum &&
diff --git a/com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/stats/Chisq.java b/com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/stats/Chisq.java
index c39fa8c5e71ef0ff5c84add184ea21ccee6cd3df..45042cb0493b22e9a7acb3e26fe87018b9456cb6 100644
--- a/com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/stats/Chisq.java
+++ b/com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/stats/Chisq.java
@@ -13,11 +13,18 @@ package com.oracle.truffle.r.library.stats;
 
 import static com.oracle.truffle.r.library.stats.GammaFunctions.dgamma;
 import static com.oracle.truffle.r.library.stats.GammaFunctions.pgamma;
+import static com.oracle.truffle.r.library.stats.GammaFunctions.qgamma;
 
+import com.oracle.truffle.r.library.stats.RandGenerationFunctions.RandFunction1_Double;
+import com.oracle.truffle.r.library.stats.RandGenerationFunctions.RandomNumberProvider;
 import com.oracle.truffle.r.library.stats.StatsFunctions.Function2_1;
 import com.oracle.truffle.r.library.stats.StatsFunctions.Function2_2;
 
 public final class Chisq {
+    private Chisq() {
+        // only static members
+    }
+
     public static final class PChisq implements Function2_2 {
         @Override
         public double evaluate(double x, double df, boolean lowerTail, boolean logP) {
@@ -31,4 +38,25 @@ public final class Chisq {
             return dgamma(x, df / 2., 2., giveLog);
         }
     }
+
+    public static final class QChisq implements Function2_2 {
+        @Override
+        public double evaluate(double p, double df, boolean lowerTail, boolean logP) {
+            return qgamma(p, 0.5 * df, 2.0, lowerTail, logP);
+        }
+    }
+
+    public static final class RChisq extends RandFunction1_Double {
+        public static double rchisq(double df, RandomNumberProvider rand) {
+            if (!Double.isFinite(df) || df < 0.0) {
+                return RMathError.defaultError();
+            }
+            return new RGamma().execute(df / 2.0, 2.0, rand);
+        }
+
+        @Override
+        public double execute(double a, RandomNumberProvider rand) {
+            return rchisq(a, rand);
+        }
+    }
 }
diff --git a/com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/stats/DBeta.java b/com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/stats/DBeta.java
index a6a5a767d9e71e9bf4b8f8baa772bdaaf1124178..4b60d50296b000f4429f2319139819b1356b9cf7 100644
--- a/com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/stats/DBeta.java
+++ b/com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/stats/DBeta.java
@@ -16,7 +16,7 @@ import static com.oracle.truffle.r.library.stats.LBeta.lbeta;
 
 import com.oracle.truffle.r.library.stats.StatsFunctions.Function3_1;
 
-public class DBeta implements Function3_1 {
+public final class DBeta implements Function3_1 {
     @Override
     public double evaluate(double x, double a, double b, boolean log) {
         /* NaNs propagated correctly */
@@ -25,7 +25,7 @@ public class DBeta implements Function3_1 {
         }
 
         if (a < 0 || b < 0) {
-            return RMath.mlError();
+            return RMathError.defaultError();
         }
         if (x < 0 || x > 1) {
             return (DPQ.rd0(log));
diff --git a/com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/stats/DHyper.java b/com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/stats/DHyper.java
new file mode 100644
index 0000000000000000000000000000000000000000..1b569cd453911da9fad0b91b87b5804672d57dba
--- /dev/null
+++ b/com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/stats/DHyper.java
@@ -0,0 +1,65 @@
+/*
+ * This material is distributed under the GNU General Public License
+ * Version 2. You may review the terms of this license at
+ * http://www.gnu.org/licenses/gpl-2.0.html
+ *
+ * Copyright (c) 2000-2014, The R Core Team
+ * Copyright (c) 2016, Oracle and/or its affiliates
+ *
+ * All rights reserved.
+ */
+/*
+ *  AUTHOR
+ *    Catherine Loader, catherine@research.bell-labs.com.
+ *    October 23, 2000.
+ *
+ */
+package com.oracle.truffle.r.library.stats;
+
+import static com.oracle.truffle.r.library.stats.Dbinom.dbinomRaw;
+
+import com.oracle.truffle.r.library.stats.DPQ.EarlyReturn;
+import com.oracle.truffle.r.library.stats.StatsFunctions.Function4_1;
+
+public final class DHyper implements Function4_1 {
+    @Override
+    public double evaluate(double x, double r, double b, double n, boolean giveLog) {
+        if (Double.isNaN(x) || Double.isNaN(r) || Double.isNaN(b) || Double.isNaN(n)) {
+            return x + r + b + n;
+        }
+
+        if (DPQ.rdneginonint(r) || DPQ.rdneginonint(b) || DPQ.rdneginonint(n) || n > r + b) {
+            return RMathError.defaultError();
+        }
+        if (x < 0) {
+            return DPQ.rd0(giveLog);
+        }
+
+        try {
+            DPQ.nonintCheck(x, giveLog); // incl warning
+        } catch (EarlyReturn e) {
+            return e.result;
+        }
+
+        double ix = RMath.forceint(x);
+        double ir = RMath.forceint(r);
+        double ib = RMath.forceint(b);
+        double in = RMath.forceint(n);
+
+        if (in < ix || ir < ix || in - ix > ib) {
+            return DPQ.rd0(giveLog);
+        }
+        if (in == 0) {
+            return (ix == 0) ? DPQ.rd1(giveLog) : DPQ.rd0(giveLog);
+        }
+
+        double p = in / (ir + ib);
+        double q = (ir + ib - in) / (ir + ib);
+
+        double p1 = dbinomRaw(ix, ir, p, q, giveLog);
+        double p2 = dbinomRaw(in - ix, ib, p, q, giveLog);
+        double p3 = dbinomRaw(in, ir + ib, p, q, giveLog);
+
+        return (giveLog) ? p1 + p2 - p3 : p1 * p2 / p3;
+    }
+}
diff --git a/com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/stats/DNBeta.java b/com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/stats/DNBeta.java
new file mode 100644
index 0000000000000000000000000000000000000000..c357b66df5d85cd3cc187e6fde1abc17771e07b1
--- /dev/null
+++ b/com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/stats/DNBeta.java
@@ -0,0 +1,94 @@
+/*
+ * This material is distributed under the GNU General Public License
+ * Version 2. You may review the terms of this license at
+ * http://www.gnu.org/licenses/gpl-2.0.html
+ *
+ * Copyright (C) 1998 Ross Ihaka
+ * Copyright (c) 2000-12, The R Core Team
+ * Copyright (c) 2016, Oracle and/or its affiliates
+ *
+ * All rights reserved.
+ */
+package com.oracle.truffle.r.library.stats;
+
+import static com.oracle.truffle.r.library.stats.GammaFunctions.dpoisRaw;
+
+import com.oracle.truffle.r.library.stats.StatsFunctions.Function4_1;
+
+public final class DNBeta implements Function4_1 {
+    private static final double eps = 1.e-15;
+    private final DBeta dbeta = new DBeta();
+
+    @Override
+    public double evaluate(double x, double a, double b, double ncp, boolean giveLog) {
+        if (Double.isNaN(x) || Double.isNaN(a) || Double.isNaN(b) || Double.isNaN(ncp)) {
+            return x + a + b + ncp;
+        }
+        if (ncp < 0 || a <= 0 || b <= 0 || !Double.isFinite(a) || !Double.isFinite(b) || !Double.isFinite(ncp)) {
+            return RMathError.defaultError();
+        }
+
+        if (x < 0 || x > 1) {
+            return DPQ.rd0(giveLog);
+        }
+        if (ncp == 0) {
+            return dbeta.evaluate(x, a, b, giveLog);
+        }
+
+        /* New algorithm, starting with *largest* term : */
+        double ncp2 = 0.5 * ncp;
+        double dx2 = ncp2 * x;
+        double d = (dx2 - a - 1) / 2;
+        double capD = d * d + dx2 * (a + b) - a;
+        int kMax;
+        if (capD <= 0) {
+            kMax = 0;
+        } else {
+            capD = Math.ceil(d + Math.sqrt(capD));
+            kMax = (capD > 0) ? (int) capD : 0;
+        }
+
+        /* The starting "middle term" --- first look at it's log scale: */
+        double term = dbeta.evaluate(x, a + kMax, b, /* log = */ true);
+        /* LDOUBLE */double pK = dpoisRaw(kMax, ncp2, true);
+        if (x == 0. || !Double.isFinite(term) || !Double.isFinite(pK)) {
+            /* if term = +Inf */
+            return DPQ.rdexp(pK + term, giveLog);
+        }
+
+        /*
+         * Now if s_k := pK * t_k {here = Math.exp(pK + term)} would underflow, we should rather
+         * scale everything and re-scale at the end:
+         */
+
+        pK += term; /*
+                     * = Math.log(pK) + Math.log(t_k) == Math.log(s_k) -- used at end to rescale
+                     */
+        /* mid = 1 = the rescaled value, instead of mid = Math.exp(pK); */
+
+        /* Now sum from the inside out */
+        /* LDOUBLE */double sum = term = 1. /* = mid term */;
+        /* middle to the left */
+        int k = kMax;
+        while (k > 0 && term > sum * eps) {
+            k--;
+            /* LDOUBLE */double q = /* 1 / r_k = */ (k + 1) * (k + a) / (k + a + b) / dx2;
+            term *= q;
+            sum += term;
+        }
+        /* middle to the right */
+        term = 1.;
+        k = kMax;
+        do {
+            /* LDOUBLE */double q = /* r_{old k} = */ dx2 * (k + a + b) / (k + a) / (k + 1);
+            k++;
+            term *= q;
+            sum += term;
+        } while (term > sum * eps);
+
+        // #ifdef HAVE_LONG_DOUBLE
+        // return DPQ.rdMath.exp((double)(pK + logl(sum)));
+        // #else
+        return DPQ.rdexp(pK + Math.log(sum), giveLog);
+    }
+}
diff --git a/com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/stats/DNChisq.java b/com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/stats/DNChisq.java
new file mode 100644
index 0000000000000000000000000000000000000000..8fe5845b3441e24e8921e601459456e7347eb6ac
--- /dev/null
+++ b/com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/stats/DNChisq.java
@@ -0,0 +1,115 @@
+/*
+ * This material is distributed under the GNU General Public License
+ * Version 2. You may review the terms of this license at
+ * http://www.gnu.org/licenses/gpl-2.0.html
+ *
+ * Copyright (C) 1998 Ross Ihaka
+ * Copyright (c) 2000-15, The R Core Team
+ * Copyright (c) 2004-15, The R Foundation
+ * Copyright (c) 2016, Oracle and/or its affiliates
+ *
+ * All rights reserved.
+ */
+package com.oracle.truffle.r.library.stats;
+
+import static com.oracle.truffle.r.library.stats.GammaFunctions.dpoisRaw;
+
+import com.oracle.truffle.r.library.stats.Chisq.DChisq;
+import com.oracle.truffle.r.library.stats.StatsFunctions.Function3_1;
+
+public final class DNChisq implements Function3_1 {
+    private static final double eps = 5e-15;
+    private final DChisq dchisq = new DChisq();
+
+    @Override
+    public double evaluate(double x, double df, double ncp, boolean giveLog) {
+        if (Double.isNaN(x) || Double.isNaN(df) || Double.isNaN(ncp)) {
+            return x + df + ncp;
+        }
+
+        if (!Double.isFinite(df) || !Double.isFinite(ncp) || ncp < 0 || df < 0) {
+            return RMathError.defaultError();
+        }
+
+        if (x < 0) {
+            return DPQ.rd0(giveLog);
+        }
+        if (x == 0 && df < 2.) {
+            return Double.POSITIVE_INFINITY;
+        }
+        if (ncp == 0) {
+            return (df > 0) ? dchisq.evaluate(x, df, giveLog) : DPQ.rd0(giveLog);
+        }
+        if (x == Double.POSITIVE_INFINITY) {
+            return DPQ.rd0(giveLog);
+        }
+
+        double ncp2 = 0.5 * ncp;
+
+        /* find max element of sum */
+        double imax = Math.ceil((-(2 + df) + Math.sqrt((2 - df) * (2 - df) + 4 * ncp * x)) / 4);
+        double mid;
+        double dfmid = 0;   // Note: not initialized in GnuR
+        if (imax < 0) {
+            imax = 0;
+        }
+        if (Double.isFinite(imax)) {
+            dfmid = df + 2 * imax;
+            mid = dpoisRaw(imax, ncp2, false) * dchisq.evaluate(x, dfmid, false);
+        } else {
+            /* imax = Inf */
+            mid = 0;
+        }
+
+        if (mid == 0) {
+            /*
+             * underflow to 0 -- maybe numerically correct; maybe can be more accurate, particularly
+             * when giveLog = true
+             */
+            /*
+             * Use central-chisq approximation formula when appropriate; ((FIXME: the optimal cutoff
+             * also depends on (x,df); use always here? ))
+             */
+            if (giveLog || ncp > 1000.) {
+                /* = "1/(1+b)" Abramowitz & St. */
+                double nl = df + ncp;
+                double ic = nl / (nl + ncp);
+                return dchisq.evaluate(x * ic, nl * ic, giveLog);
+            } else {
+                return DPQ.rd0(giveLog);
+            }
+        }
+
+        /* errorbound := term * q / (1-q) now subsumed in while() / if () below: */
+
+        /* upper tail */
+        /* LDOUBLE */double sum = mid;
+        /* LDOUBLE */double term = mid;
+        double df2 = dfmid;
+        double i = imax;
+        double x2 = x * ncp2;
+        double q;
+        do {
+            i++;
+            q = x2 / i / df2;
+            df2 += 2;
+            term *= q;
+            sum += term;
+        } while (q >= 1 || term * q > (1 - q) * eps || term > 1e-10 * sum);
+        /* lower tail */
+        term = mid;
+        df2 = dfmid;
+        i = imax;
+        while (i != 0) {
+            df2 -= 2;
+            q = i * df2 / x2;
+            i--;
+            term *= q;
+            sum += term;
+            if (q < 1 && term * q <= (1 - q) * eps) {
+                break;
+            }
+        }
+        return DPQ.rdval(sum, giveLog);
+    }
+}
diff --git a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/foreign/Dnorm4.java b/com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/stats/DNorm.java
similarity index 53%
rename from com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/foreign/Dnorm4.java
rename to com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/stats/DNorm.java
index f5d055b8b88e45c2735aa4a2ec34077ae4ed018c..bdccc0beeb7c66a8ca335a843177f8784d989c83 100644
--- a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/foreign/Dnorm4.java
+++ b/com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/stats/DNorm.java
@@ -10,18 +10,14 @@
  * All rights reserved.
  */
 
-package com.oracle.truffle.r.nodes.builtin.base.foreign;
+package com.oracle.truffle.r.library.stats;
 
-import com.oracle.truffle.r.library.stats.StatsFunctions.Function3_1;
-
-/**
- * Called from 'dnorm' R wrapper.
- */
-public final class Dnorm4 implements Function3_1 {
+import static com.oracle.truffle.r.library.stats.MathConstants.M_1_SQRT_2PI;
+import static com.oracle.truffle.r.library.stats.MathConstants.M_LN_SQRT_2PI;
 
-    private static final double M_LN_SQRT_2PI = 0.918938533204672741780329736406;
-    private static final double M_1_SQRT_2PI = 0.398942280401432677939946059934;
+import com.oracle.truffle.r.library.stats.StatsFunctions.Function3_1;
 
+public final class DNorm implements Function3_1 {
     @Override
     public double evaluate(double xa, double mu, double sigma, boolean giveLog) {
         double x = xa;
@@ -29,26 +25,29 @@ public final class Dnorm4 implements Function3_1 {
             return x + mu + sigma;
         }
 
-        double negInfOrZero = giveLog ? Double.NEGATIVE_INFINITY : 0; // in GnuR R_D__0
         if (!Double.isFinite(sigma)) {
-            return negInfOrZero;
-        } else if (!Double.isFinite(x) && !Double.isFinite(mu)) {
-            return Double.NaN;
+            return DPQ.rd0(giveLog);
+        } else if (!Double.isFinite(x) && mu == x) {
+            return RMathError.defaultError();
         } else if (sigma <= 0) {
             if (sigma < 0) {
-                // TODO: ML_ERR_return_NAN (what is it supposed to do? GnuR does not print anything)
-                return Double.NaN;
+                return RMathError.defaultError();
             }
-            return (x == mu) ? Double.POSITIVE_INFINITY : negInfOrZero;
+            return (x == mu) ? Double.POSITIVE_INFINITY : DPQ.rd0(giveLog);
         }
 
         x = (x - mu) / sigma;
+        x = Math.abs(x);
+        if (x >= 2 * Math.sqrt(Double.MAX_VALUE)) {
+            return DPQ.rd0(giveLog);
+        }
+
         if (!Double.isFinite(x)) {
-            return negInfOrZero;
+            return DPQ.rd0(giveLog);
         }
 
         if (giveLog) {
-            return -(M_LN_SQRT_2PI + 0.5 * x * x + Math.log10(sigma));
+            return -(M_LN_SQRT_2PI + 0.5 * x * x + Math.log(sigma));
         }
         return M_1_SQRT_2PI * Math.exp(-0.5 * x * x) / sigma;
     }
diff --git a/com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/stats/DPQ.java b/com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/stats/DPQ.java
index 4925be2e7668b809c858a9ab8357bf45df62bcdb..2ec4f83eaa7441ee8cb89ea6752bfcf15bedcb0a 100644
--- a/com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/stats/DPQ.java
+++ b/com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/stats/DPQ.java
@@ -12,7 +12,6 @@ package com.oracle.truffle.r.library.stats;
 
 import static com.oracle.truffle.r.library.stats.MathConstants.M_LN2;
 
-import com.oracle.truffle.api.nodes.ControlFlowException;
 import com.oracle.truffle.r.runtime.RError;
 import com.oracle.truffle.r.runtime.RError.Message;
 
@@ -26,19 +25,25 @@ public final class DPQ {
         // only static methods
     }
 
-    public static final class EarlyReturn extends ControlFlowException {
+    public static final class EarlyReturn extends Exception {
         private static final long serialVersionUID = 1182697355931636213L;
         public final double result;
 
         private EarlyReturn(double result) {
             this.result = result;
         }
+
+        @SuppressWarnings("sync-override")
+        @Override
+        public Throwable fillInStackTrace() {
+            return null;
+        }
     }
 
     // R >= 3.1.0: # define R_nonint(x) (fabs((x) - R_forceint(x)) > 1e-7)
     // Note: if true should be followed by "return d0(logP)", consider using nointCheck instead
     public static boolean nonint(double x) {
-        return Math.abs(x - Math.round(x)) > 1e-7 * Math.max(1., Math.abs(x));
+        return Math.abs(x - RMath.forceint(x)) > 1e-7 * Math.max(1., Math.abs(x));
     }
 
     // R_D__0
@@ -46,6 +51,11 @@ public final class DPQ {
         return logP ? Double.NEGATIVE_INFINITY : 0.;
     }
 
+    // R_D_half (log_p ? -M_LN2 : 0.5)
+    public static double rdhalf(boolean logP) {
+        return logP ? -M_LN2 : 0.5;
+    }
+
     // R_D__1
     public static double rd1(boolean logP) {
         return logP ? 0. : 1.;
@@ -71,6 +81,7 @@ public final class DPQ {
     }
 
     // R_D_Lval
+    // Use 0.5 - p + 0.5 to perhaps gain 1 bit of accuracy
     public static double rdlval(double p, boolean lowerTail) {
         return lowerTail ? p : 0.5 - p + 0.5;
     }
@@ -84,6 +95,11 @@ public final class DPQ {
         return logP ? Math.log(x) : x; /* x in pF(x,..) */
     }
 
+    // R_DT_val
+    public static double rdtval(double x, boolean lowerTail, boolean logP) {
+        return lowerTail ? rdval(x, true) : rdclog(x, logP);
+    }
+
     public static double rdexp(double x, boolean logP) {
         return logP ? x : Math.exp(x); /* exp(x) */
     }
@@ -112,6 +128,11 @@ public final class DPQ {
         return logP ? RMath.log1p(-(p)) : (0.5 - (p) + 0.5);
     }
 
+    // R_D_qIv (log_p ? exp(p) : (p))
+    public static double rdqiv(double p, boolean logP) {
+        return logP ? Math.exp(p) : p;
+    }
+
     // R_DT_qIv
     public static double rdtqiv(double p, boolean lowerTail, boolean logP) {
         return logP ? lowerTail ? Math.exp(p) : -Math.expm1(p) : rdlval(p, lowerTail);
@@ -122,6 +143,12 @@ public final class DPQ {
         return logP ? lowerTail ? -Math.expm1(p) : Math.exp(p) : rdcval(p, lowerTail);
     }
 
+    /* [neg]ative or [non int]eger : */
+    // R_D_negInonint
+    public static boolean rdneginonint(double x) {
+        return x < 0. || nonint(x);
+    }
+
     // R_Q_P01_boundaries
     public static void rqp01boundaries(double p, double left, double right, boolean lowerTail, boolean logP) throws EarlyReturn {
         if (logP) {
@@ -148,10 +175,26 @@ public final class DPQ {
         }
     }
 
+    // R_P_bounds_01
+    public static void rpbounds01(double x, double xMin, double xMax, boolean lowerTail, boolean logP) throws EarlyReturn {
+        if (x <= xMin) {
+            throw new EarlyReturn(rdt0(lowerTail, logP));
+        } else if (x >= xMax) {
+            throw new EarlyReturn(rdt1(lowerTail, logP));
+        }
+    }
+
+    // R_P_bounds_Inf_01
+    public static void rpboundsinf01(double x, boolean lowerTail, boolean logP) throws EarlyReturn {
+        if (!Double.isFinite(x)) {
+            throw new EarlyReturn(x > 0 ? rdt1(lowerTail, logP) : rdt0(lowerTail, logP));
+        }
+    }
+
     // R_Q_P01_check
     public static void rqp01check(double p, boolean logP) throws EarlyReturn {
         if ((logP && p > 0) || (!logP && (p < 0 || p > 1))) {
-            throw new EarlyReturn(RMath.mlError());
+            throw new EarlyReturn(RMathError.defaultError());
         }
     }
 
diff --git a/com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/stats/DPois.java b/com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/stats/DPois.java
index b01d2a4d75603a4b862849e498ef24a41ce0e167..bc14734a766afbf46ea03e5df58082a6f4701d47 100644
--- a/com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/stats/DPois.java
+++ b/com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/stats/DPois.java
@@ -13,7 +13,7 @@
 package com.oracle.truffle.r.library.stats;
 
 import static com.oracle.truffle.r.library.stats.GammaFunctions.dpoisRaw;
-import static com.oracle.truffle.r.library.stats.MathConstants.forceint;
+import static com.oracle.truffle.r.library.stats.RMath.forceint;
 
 import com.oracle.truffle.r.library.stats.DPQ.EarlyReturn;
 import com.oracle.truffle.r.library.stats.StatsFunctions.Function2_1;
@@ -25,7 +25,7 @@ public final class DPois implements Function2_1 {
             return x + lambda;
         }
         if (lambda < 0) {
-            return RMath.mlError();
+            return RMathError.defaultError();
         }
 
         try {
diff --git a/com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/stats/Dbinom.java b/com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/stats/Dbinom.java
index 509f543c81aeb163e1eb86ccf6725ea40a88f95d..0486d311a7cce855fd617c28224dae4a39454e27 100644
--- a/com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/stats/Dbinom.java
+++ b/com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/stats/Dbinom.java
@@ -88,6 +88,6 @@ public final class Dbinom implements StatsFunctions.Function3_1 {
             return DPQ.rd0(giveLog);
         }
 
-        return dbinomRaw(MathConstants.forceint(x), MathConstants.forceint(n), p, 1 - p, giveLog);
+        return dbinomRaw(RMath.forceint(x), RMath.forceint(n), p, 1 - p, giveLog);
     }
 }
diff --git a/com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/stats/Df.java b/com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/stats/Df.java
index ded5ed50571f78b97300e4c76b7d0cdab74cb34c..90d58c8260899f869da8eaac02f191aff3660c80 100644
--- a/com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/stats/Df.java
+++ b/com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/stats/Df.java
@@ -30,7 +30,7 @@ public final class Df implements Function3_1 {
         }
 
         if (m <= 0 || n <= 0) {
-            return RMath.mlError();
+            return RMathError.defaultError();
         }
         if (x < 0.) {
             return DPQ.rd0(giveLog);
diff --git a/com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/stats/Dnf.java b/com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/stats/Dnf.java
new file mode 100644
index 0000000000000000000000000000000000000000..2afc8f5e130857118685fbf31b2c191a7e564833
--- /dev/null
+++ b/com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/stats/Dnf.java
@@ -0,0 +1,78 @@
+/*
+ * This material is distributed under the GNU General Public License
+ * Version 2. You may review the terms of this license at
+ * http://www.gnu.org/licenses/gpl-2.0.html
+ *
+ * Copyright (c) 2006, The R Core Team
+ * Copyright (c) 2016, Oracle and/or its affiliates
+ *
+ * All rights reserved.
+ */
+/*
+ *  AUTHOR
+ *    Peter Ruckdeschel, peter.ruckdeschel@uni-bayreuth.de.
+ *    April 13, 2006.
+ *
+ */
+package com.oracle.truffle.r.library.stats;
+
+import static com.oracle.truffle.r.library.stats.GammaFunctions.dgamma;
+
+import com.oracle.truffle.r.library.stats.StatsFunctions.Function4_1;
+
+public final class Dnf implements Function4_1 {
+    private final DNChisq dnchisq = new DNChisq();
+    private final DNBeta dnbeta = new DNBeta();
+
+    @Override
+    public double evaluate(double x, double df1, double df2, double ncp, boolean giveLog) {
+        if (Double.isNaN(x) || Double.isNaN(df1) || Double.isNaN(df2) || Double.isNaN(ncp)) {
+            return x + df2 + df1 + ncp;
+        }
+
+        /*
+         * want to compare dnf(ncp=0) behavior with df() one, hence *NOT* : if (ncp == 0) return
+         * df(x, df1, df2, giveLog);
+         */
+
+        if (df1 <= 0. || df2 <= 0. || ncp < 0) {
+            return RMathError.defaultError();
+        }
+        if (x < 0.) {
+            return DPQ.rd0(giveLog);
+        }
+        if (!Double.isFinite(ncp)) {
+            /* ncp = +Inf -- GnuR: fix me?: in some cases, limit exists */
+            return RMathError.defaultError();
+        }
+
+        /*
+         * This is not correct for df1 == 2, ncp > 0 - and seems unneeded: if (x == 0.) { return(df1
+         * > 2 ? DPQ.rd0(log_p) : (df1 == 2 ? DPQ.rd1 : Double.POSITIVE_INFINITY)); }
+         */
+        if (!Double.isFinite(df1) && !Double.isFinite(df2)) {
+            /* both +Inf */
+            /* PR: not sure about this (taken from ncp==0) -- GnuR fix me ? */
+            if (x == 1.) {
+                return Double.POSITIVE_INFINITY;
+            } else {
+                return DPQ.rd0(giveLog);
+            }
+        }
+        if (!Double.isFinite(df2)) {
+            /* i.e. = +Inf */
+            return df1 * dnchisq.evaluate(x * df1, df1, ncp, giveLog);
+        }
+        /* == dngamma(x, df1/2, 2./df1, ncp, giveLog) -- but that does not exist */
+        if (df1 > 1e14 && ncp < 1e7) {
+            /* includes df1 == +Inf: code below is inaccurate there */
+            double f = 1 + ncp / df1; /* assumes ncp << df1 [ignores 2*ncp^(1/2)/df1*x term] */
+            double z = dgamma(1. / x / f, df2 / 2, 2. / df2, giveLog);
+            return giveLog ? z - 2 * Math.log(x) - Math.log(f) : z / (x * x) / f;
+        }
+
+        double y = (df1 / df2) * x;
+        double z = dnbeta.evaluate(y / (1 + y), df1 / 2., df2 / 2., ncp, giveLog);
+        return giveLog ? z + Math.log(df1) - Math.log(df2) - 2 * RMath.log1p(y) : z * (df1 / df2) / (1 + y) / (1 + y);
+    }
+}
diff --git a/com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/stats/Dt.java b/com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/stats/Dt.java
index 62245897573ddf9e784b89fd9b97acd1d21fa249..45eb01fe6b8bd4ead373dccfced2c307d3e50321 100644
--- a/com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/stats/Dt.java
+++ b/com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/stats/Dt.java
@@ -13,7 +13,6 @@
 package com.oracle.truffle.r.library.stats;
 
 import static com.oracle.truffle.r.library.stats.GammaFunctions.bd0;
-import static com.oracle.truffle.r.library.stats.GammaFunctions.dnorm;
 import static com.oracle.truffle.r.library.stats.GammaFunctions.stirlerr;
 import static com.oracle.truffle.r.library.stats.MathConstants.DBL_EPSILON;
 import static com.oracle.truffle.r.library.stats.MathConstants.M_1_SQRT_2PI;
@@ -22,6 +21,8 @@ import static com.oracle.truffle.r.library.stats.MathConstants.M_LN_SQRT_2PI;
 import com.oracle.truffle.r.library.stats.StatsFunctions.Function2_1;
 
 public final class Dt implements Function2_1 {
+    private static final DNorm dnorm = new DNorm();
+
     @Override
     public double evaluate(double x, double n, boolean giveLog) {
         if (Double.isNaN(x) || Double.isNaN(n)) {
@@ -29,14 +30,14 @@ public final class Dt implements Function2_1 {
         }
 
         if (n <= 0) {
-            return RMath.mlError();
+            return RMathError.defaultError();
         }
 
         if (!Double.isFinite(x)) {
             return DPQ.rd0(giveLog);
         }
         if (!Double.isFinite(n)) {
-            return dnorm(x, 0., 1., giveLog);
+            return dnorm.evaluate(x, 0., 1., giveLog);
         }
 
         double u;
diff --git a/com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/stats/Exp.java b/com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/stats/Exp.java
index 05c81882607860c2964fcd497ca817555579a8b3..76df1c61e95011c8b3b089db0dbb1b7852061cb6 100644
--- a/com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/stats/Exp.java
+++ b/com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/stats/Exp.java
@@ -17,7 +17,11 @@ import com.oracle.truffle.r.library.stats.RandGenerationFunctions.RandomNumberPr
 import com.oracle.truffle.r.library.stats.StatsFunctions.Function2_1;
 import com.oracle.truffle.r.library.stats.StatsFunctions.Function2_2;
 
-public class Exp {
+public final class Exp {
+    private Exp() {
+        // only static members
+    }
+
     public static final class DExp implements Function2_1 {
         @Override
         public double evaluate(double x, double scale, boolean giveLog) {
@@ -27,7 +31,7 @@ public class Exp {
             }
 
             if (scale <= 0.0) {
-                return RMath.mlError();
+                return RMathError.defaultError();
             }
 
             if (x < 0.) {
@@ -37,11 +41,11 @@ public class Exp {
         }
     }
 
-    public static final class RExp implements RandFunction1_Double {
+    public static final class RExp extends RandFunction1_Double {
         @Override
-        public double evaluate(double scale, RandomNumberProvider rand) {
+        public double execute(double scale, RandomNumberProvider rand) {
             if (!Double.isFinite(scale) || scale <= 0.0) {
-                return scale == 0. ? 0. : RMath.mlError();
+                return scale == 0. ? 0. : RMathError.defaultError();
             }
             return scale * rand.expRand();
         }
@@ -49,20 +53,20 @@ public class Exp {
 
     public static final class PExp implements Function2_2 {
         @Override
-        public double evaluate(double x, double scale, boolean lowerTail, boolean logP) {
-            if (Double.isNaN(x) || Double.isNaN(scale)) {
-                return x + scale;
+        public double evaluate(double xIn, double scale, boolean lowerTail, boolean logP) {
+            if (Double.isNaN(xIn) || Double.isNaN(scale)) {
+                return xIn + scale;
             }
             if (scale < 0) {
-                return RMath.mlError();
+                return RMathError.defaultError();
             }
 
-            if (x <= 0.) {
+            if (xIn <= 0.) {
                 return DPQ.rdt0(lowerTail, logP);
             }
 
             /* same as weibull( shape = 1): */
-            x = -(x / scale);
+            double x = -(xIn / scale);
             return lowerTail ? (logP ? DPQ.rlog1exp(x) : -RMath.expm1(x)) : DPQ.rdexp(x, logP);
         }
     }
@@ -75,7 +79,7 @@ public class Exp {
             }
 
             if (scale < 0) {
-                return RMath.mlError();
+                return RMathError.defaultError();
             }
 
             try {
@@ -89,7 +93,6 @@ public class Exp {
             }
 
             return -scale * DPQ.rdtclog(p, lowerTail, logP);
-
         }
     }
 }
diff --git a/com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/stats/GammaFunctions.java b/com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/stats/GammaFunctions.java
index 1638c38e2ce080d756db52c1c368bd0c9044230a..8b221ce9340d4d5f9701d510a3ac14de224879ac 100644
--- a/com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/stats/GammaFunctions.java
+++ b/com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/stats/GammaFunctions.java
@@ -28,6 +28,7 @@ import static com.oracle.truffle.r.library.stats.DPQ.rdtclog;
 import static com.oracle.truffle.r.library.stats.DPQ.rdtqiv;
 import static com.oracle.truffle.r.library.stats.DPQ.rlog1exp;
 import static com.oracle.truffle.r.library.stats.MathConstants.DBL_EPSILON;
+import static com.oracle.truffle.r.library.stats.MathConstants.DBL_MIN;
 import static com.oracle.truffle.r.library.stats.MathConstants.M_1_SQRT_2PI;
 import static com.oracle.truffle.r.library.stats.MathConstants.M_2PI;
 import static com.oracle.truffle.r.library.stats.MathConstants.M_LN2;
@@ -37,10 +38,12 @@ import static com.oracle.truffle.r.library.stats.RMath.fmax2;
 import com.oracle.truffle.api.CompilerDirectives.CompilationFinal;
 import com.oracle.truffle.api.CompilerDirectives.TruffleBoundary;
 import com.oracle.truffle.r.library.stats.DPQ.EarlyReturn;
+import com.oracle.truffle.r.library.stats.RMathError.MLError;
 import com.oracle.truffle.r.library.stats.StatsFunctions.Function3_1;
 import com.oracle.truffle.r.library.stats.StatsFunctions.Function3_2;
-import com.oracle.truffle.r.runtime.RError;
+import com.oracle.truffle.r.runtime.RError.Message;
 import com.oracle.truffle.r.runtime.RRuntime;
+import com.oracle.truffle.r.runtime.Utils;
 import com.oracle.truffle.r.runtime.ops.BinaryArithmetic;
 
 /**
@@ -178,8 +181,8 @@ public abstract class GammaFunctions {
             // TODO ML_ERR_return_NAN
             return Double.NaN;
         } else if (x >= lgc_xmax) {
-            // ML_ERROR(ME_UNDERFLOW, "lgammacor");
             /* allow to underflow below */
+            RMathError.error(MLError.UNDERFLOW, "lgammacor");
         } else if (x < xbig) {
             tmp = 10 / x;
             return RMath.chebyshevEval(tmp * tmp * 2 - 1, ALGMCS, nalgm) / x;
@@ -187,8 +190,12 @@ public abstract class GammaFunctions {
         return 1 / (x * 12);
     }
 
-    static double lgamma(double x) {
-        throw RError.nyi(RError.SHOW_CALLER, "lgamma from libc");
+    /**
+     * Should be used in places where GnuR itself uses std libc function {@code lgamma}. Under the
+     * hood it uses {@link #lgammafn(double)}.
+     */
+    static double lgamma(@SuppressWarnings("unused") double x) {
+        return lgammafn(x);
     }
 
     //
@@ -266,7 +273,7 @@ public abstract class GammaFunctions {
                 /* The answer is less than half precision */
                 /* because x too near a negative integer. */
                 if (x < -0.5 && Math.abs(x - (int) (x - 0.5) / x) < gfn_dxrel) {
-                    // ML_ERROR(ME_PRECISION, "gammafn");
+                    RMathError.error(MLError.PRECISION, "gammafn");
                 }
 
                 /* The argument is so close to 0 that the result would overflow. */
@@ -319,16 +326,14 @@ public abstract class GammaFunctions {
             }
 
             if (Math.abs((x - (int) (x - 0.5)) / x) < gfn_dxrel) {
-
                 /* The answer is less than half precision because */
                 /* the argument is too near a negative integer. */
-
-                // ML_ERROR(ME_PRECISION, "gammafn");
+                RMathError.error(MLError.PRECISION, "gammafn");
             }
 
             sinpiy = Math.sin(Math.PI * y);
             if (sinpiy == 0) { /* Negative integer arg - overflow */
-                // ML_ERROR(ME_RANGE, "gammafn");
+                RMathError.error(MLError.RANGE, "gammafn");
                 return Double.POSITIVE_INFINITY;
             }
 
@@ -371,7 +376,7 @@ public abstract class GammaFunctions {
         }
 
         if (x <= 0 && x == (long) x) { /* Negative integer argument */
-            RError.warning(RError.SHOW_CALLER, RError.Message.VALUE_OUT_OF_RANGE, "lgamma");
+            RMathError.error(MLError.RANGE, "lgamma");
             return Double.POSITIVE_INFINITY; /* +Inf, since lgamma(x) = log|gamma(x)| */
         }
 
@@ -388,7 +393,7 @@ public abstract class GammaFunctions {
          */
 
         if (y > gfn_sign_xmax) {
-            RError.warning(RError.SHOW_CALLER, RError.Message.VALUE_OUT_OF_RANGE, "lgamma");
+            RMathError.error(MLError.RANGE, "lgamma");
             return Double.POSITIVE_INFINITY;
         }
 
@@ -407,21 +412,18 @@ public abstract class GammaFunctions {
         if (sinpiy == 0) { /*
                             * Negative integer argument === Now UNNECESSARY: caught above
                             */
-            // MATHLIB_WARNING(" ** should NEVER happen! *** [lgamma.c: Neg.int, y=%g]\n",y);
-            // TODO ML_ERR_return_NAN;
-            return Double.NaN;
+            RMathError.warning(Message.GENERIC, " ** should NEVER happen! *** [lgamma.c: Neg.int]");
+            return RMathError.defaultError();
         }
 
         ans = M_LN_SQRT_PId2 + (x - 0.5) * Math.log(y) - x - Math.log(sinpiy) - lgammacor(y);
 
         if (Math.abs((x - (long) (x - 0.5)) * ans / x) < gfn_sign_dxrel) {
-
             /*
              * The answer is less than half precision because the argument is too near a negative
              * integer.
              */
-
-            RError.warning(RError.SHOW_CALLER2, RError.Message.FULL_PRECISION, "lgamma");
+            RMathError.error(MLError.PRECISION, "lgamma");
         }
 
         return ans;
@@ -464,8 +466,7 @@ public abstract class GammaFunctions {
         }
 
         if (nu <= 0) {
-            // TODO ML_ERR_return_NAN;
-            return Double.NaN;
+            return RMathError.defaultError();
         }
 
         alpha = 0.5 * nu; /* = [pq]gamma() shape */
@@ -549,8 +550,7 @@ public abstract class GammaFunctions {
         // expansion of R_Q_P01_boundaries(p, 0., ML_POSINF)
         if (localLogp) {
             if (localP > 0) {
-                // TODO ML_ERR_return_NAN;
-                return Double.NaN;
+                return RMathError.defaultError();
             }
             if (localP == 0) { /* upper bound */
                 return lowerTail ? Double.POSITIVE_INFINITY : 0;
@@ -560,8 +560,7 @@ public abstract class GammaFunctions {
             }
         } else { /* !log_p */
             if (localP < 0 || localP > 1) {
-                // TODO ML_ERR_return_NAN;
-                return Double.NaN;
+                return RMathError.defaultError();
             }
             if (localP == 0) {
                 return lowerTail ? 0 : Double.POSITIVE_INFINITY;
@@ -572,8 +571,7 @@ public abstract class GammaFunctions {
         }
 
         if (alpha < 0 || scale <= 0) {
-            // TODO ML_ERR_return_NAN;
-            return Double.NaN;
+            return RMathError.defaultError();
         }
 
         if (alpha == 0) {
@@ -678,7 +676,7 @@ public abstract class GammaFunctions {
             if (x == 0) {
                 final double u1p = 1. + 1e-7;
                 final double u1m = 1. - 1e-7;
-                x = Double.MIN_VALUE;
+                x = DBL_MIN;
                 pu = pgamma(x, alpha, scale, lowerTail, localLogp);
                 if ((lowerTail && pu > localP * u1p) || (!lowerTail && pu < localP * u1m)) {
                     return 0.;
@@ -895,9 +893,8 @@ public abstract class GammaFunctions {
             if (logp) {
                 return rlog1exp(RMath.log1p(sum) + lf2);
             } else {
-                double f1m1 = sum;
                 double f2m1 = RMath.expm1(lf2);
-                return -(f1m1 + f2m1 + f1m1 * f2m1);
+                return -(sum + f2m1 + sum * f2m1);
             }
         }
     } /* pgamma_smallx() */
@@ -1011,7 +1008,7 @@ public abstract class GammaFunctions {
             }
         }
 
-        // MATHLIB_WARNING(" ** NON-convergence in pgamma()'s pd_lower_cf() f= %g.\n", f);
+        RMathError.warning(Message.GENERIC, Utils.stringFormat(" ** NON-convergence in pgamma()'s pd_lower_cf() f= %g.", f));
         return f; /* should not happen ... */
     } /* pd_lower_cf() */
 
@@ -1155,7 +1152,7 @@ public abstract class GammaFunctions {
         }
         f = res12 / elfb;
 
-        np = pnorm(s2pt, 0.0, 1.0, !lowerTail, logp);
+        np = new Pnorm().evaluate(s2pt, 0.0, 1.0, !lowerTail, logp);
 
         if (logp) {
             double ndOverP = dpnorm(s2pt, !lowerTail, np);
@@ -1166,17 +1163,15 @@ public abstract class GammaFunctions {
         }
     } /* ppois_asymp() */
 
-    private static double pgammaRaw(double x, double alph, boolean lowerTail, boolean logp) {
+    static double pgammaRaw(double x, double alph, boolean lowerTail, boolean logp) {
         /* Here, assume that (x,alph) are not NA & alph > 0 . */
 
         double res;
 
-        // expansion of R_P_bounds_01(x, 0., ML_POSINF);
-        if (x <= 0) {
-            return rdt0(lowerTail, logp);
-        }
-        if (x >= Double.POSITIVE_INFINITY) {
-            return rdt1(lowerTail, logp);
+        try {
+            DPQ.rpbounds01(x, 0., Double.POSITIVE_INFINITY, lowerTail, logp);
+        } catch (EarlyReturn e) {
+            return e.result;
         }
 
         if (x < 1) {
@@ -1219,7 +1214,7 @@ public abstract class GammaFunctions {
          * We lose a fair amount of accuracy to underflow in the cases where the final result is
          * very close to DBL_MIN. In those cases, simply redo via log space.
          */
-        if (!logp && res < Double.MIN_VALUE / DBL_EPSILON) {
+        if (!logp && res < DBL_MIN / DBL_EPSILON) {
             /* with(.Machine, double.xmin / double.eps) #|-> 1.002084e-292 */
             return Math.exp(pgammaRaw(x, alph, lowerTail, true));
         } else {
@@ -1233,8 +1228,7 @@ public abstract class GammaFunctions {
             return localX + alph + scale;
         }
         if (alph < 0. || scale <= 0.) {
-            // TODO ML_ERR_return_NAN;
-            return Double.NaN;
+            return RMathError.defaultError();
         }
         localX /= scale;
         if (Double.isNaN(localX)) { /* eg. original x = scale = +Inf */
@@ -1264,10 +1258,10 @@ public abstract class GammaFunctions {
         if (x < 0) {
             return rd0(giveLog);
         }
-        if (x <= lambda * Double.MIN_VALUE) {
+        if (x <= lambda * DBL_MIN) {
             return (rdexp(-lambda, giveLog));
         }
-        if (lambda < x * Double.MIN_VALUE) {
+        if (lambda < x * DBL_MIN) {
             return (rdexp(-lambda + x * Math.log(lambda) - lgammafn(x + 1), giveLog));
         }
         return rdfexp(M_2PI * x, -stirlerr(x) - bd0(x, lambda), giveLog);
@@ -1285,8 +1279,7 @@ public abstract class GammaFunctions {
         int j;
 
         if (!RRuntime.isFinite(x) || !RRuntime.isFinite(np) || np == 0.0) {
-            // TODO ML_ERR_return_NAN;
-            return Double.NaN;
+            return RMathError.defaultError();
         }
 
         if (Math.abs(x - np) < 0.1 * (x + np)) {
@@ -1324,8 +1317,7 @@ public abstract class GammaFunctions {
         }
         if (sigma <= 0) {
             if (sigma < 0) {
-                // TODO ML_ERR_return_NAN;
-                return Double.NaN;
+                return RMathError.defaultError();
             }
             /* sigma == 0 */
             return (localX == mu) ? Double.POSITIVE_INFINITY : rd0(giveLog);
@@ -1349,8 +1341,7 @@ public abstract class GammaFunctions {
             return x + shape + scale;
         }
         if (shape < 0 || scale <= 0) {
-            // TODO ML_ERR_return_NAN;
-            return Double.NaN;
+            return RMathError.defaultError();
         }
         if (x < 0) {
             return rd0(giveLog);
@@ -1378,46 +1369,6 @@ public abstract class GammaFunctions {
         return giveLog ? pr - Math.log(scale) : pr / scale;
     }
 
-    //
-    // pnorm
-    //
-
-    private static double pnorm(double x, double mu, double sigma, boolean lowerTail, boolean logp) {
-        double p;
-        double cp = 0;
-        double localX = x;
-
-        /*
-         * Note: The structure of these checks has been carefully thought through. For example, if x
-         * == mu and sigma == 0, we get the correct answer 1.
-         */
-        if (Double.isNaN(localX) || Double.isNaN(mu) || Double.isNaN(sigma)) {
-            return localX + mu + sigma;
-        }
-        if (!RRuntime.isFinite(localX) && mu == localX) {
-            return Double.NaN; /* x-mu is NaN */
-        }
-        if (sigma <= 0) {
-            if (sigma < 0) {
-                // TODO ML_ERR_return_NAN;
-                return Double.NaN;
-            }
-            /* sigma = 0 : */
-            return (localX < mu) ? rdt0(lowerTail, logp) : rdt1(lowerTail, logp);
-        }
-        p = (localX - mu) / sigma;
-        if (!RRuntime.isFinite(p)) {
-            return (localX < mu) ? rdt0(lowerTail, logp) : rdt1(lowerTail, logp);
-        }
-        localX = p;
-
-        double[] pa = new double[]{p};
-        double[] cpa = new double[]{cp};
-        pnormBoth(localX, pa, cpa, (lowerTail ? 0 : 1), logp);
-
-        return lowerTail ? pa[0] : cpa[0];
-    }
-
     private static final double SIXTEN = 16; /* Cutoff allowing exact "*" and "/" */
 
     @CompilationFinal private static final double[] pba = new double[]{2.2352520354606839287, 161.02823106855587881, 1067.6894854603709582, 18154.981253343561249, 0.065682337918207449113};
diff --git a/com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/stats/Geom.java b/com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/stats/Geom.java
index 2d9c81f9f15d5b506cc803b3adabdd34cf30ade5..03670cdb79897341def27dee5eaa389a5af7aa19 100644
--- a/com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/stats/Geom.java
+++ b/com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/stats/Geom.java
@@ -27,7 +27,7 @@
  */
 package com.oracle.truffle.r.library.stats;
 
-import static com.oracle.truffle.r.library.stats.MathConstants.forceint;
+import static com.oracle.truffle.r.library.stats.RMath.forceint;
 
 import com.oracle.truffle.r.library.stats.DPQ.EarlyReturn;
 import com.oracle.truffle.r.library.stats.RandGenerationFunctions.RandFunction1_Double;
@@ -35,12 +35,16 @@ import com.oracle.truffle.r.library.stats.RandGenerationFunctions.RandomNumberPr
 import com.oracle.truffle.r.library.stats.StatsFunctions.Function2_1;
 import com.oracle.truffle.r.library.stats.StatsFunctions.Function2_2;
 
-public class Geom {
+public final class Geom {
+    private Geom() {
+        // only static members
+    }
+
     public static final class QGeom implements Function2_2 {
         @Override
         public double evaluate(double p, double prob, boolean lowerTail, boolean logP) {
             if (prob <= 0 || prob > 1) {
-                return RMath.mlError();
+                return RMathError.defaultError();
             }
 
             try {
@@ -69,7 +73,7 @@ public class Geom {
                 return x + p;
             }
             if (p <= 0 || p > 1) {
-                return RMath.mlError();
+                return RMathError.defaultError();
             }
 
             try {
@@ -87,11 +91,42 @@ public class Geom {
         }
     }
 
-    public static final class RGeom implements RandFunction1_Double {
+    public static final class PGeom implements Function2_2 {
+        @Override
+        public double evaluate(double xIn, double p, boolean lowerTail, boolean logP) {
+            if (Double.isNaN(xIn) || Double.isNaN(p)) {
+                return xIn + p;
+            }
+            if (p <= 0 || p > 1) {
+                return RMathError.defaultError();
+            }
+
+            if (xIn < 0.) {
+                return DPQ.rdt0(lowerTail, logP);
+            }
+            if (!Double.isFinite(xIn)) {
+                return DPQ.rdt1(lowerTail, logP);
+            }
+            double x = Math.floor(xIn + 1e-7);
+
+            if (p == 1.) { /* we cannot assume IEEE */
+                x = lowerTail ? 1 : 0;
+                return logP ? Math.log(x) : x;
+            }
+            x = RMath.log1p(-p) * (x + 1);
+            if (logP) {
+                return DPQ.rdtclog(x, lowerTail, logP);
+            } else {
+                return lowerTail ? -RMath.expm1(x) : Math.exp(x);
+            }
+        }
+    }
+
+    public static final class RGeom extends RandFunction1_Double {
         @Override
-        public double evaluate(double p, RandomNumberProvider rand) {
+        public double execute(double p, RandomNumberProvider rand) {
             if (!Double.isFinite(p) || p <= 0 || p > 1) {
-                return RMath.mlError();
+                return RMathError.defaultError();
             }
             return RPois.rpois(rand.expRand() * ((1 - p) / p), rand);
         }
diff --git a/com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/stats/LBeta.java b/com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/stats/LBeta.java
index 8f997c3f586187da864b6cb32346d7ea03826c01..c9a23be80b668c2ff886cb970297819566ec8440 100644
--- a/com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/stats/LBeta.java
+++ b/com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/stats/LBeta.java
@@ -38,7 +38,7 @@ public final class LBeta {
 
         /* both arguments must be >= 0 */
         if (p < 0) {
-            return RMath.mlError();
+            return RMathError.defaultError();
         } else if (p == 0) {
             return Double.POSITIVE_INFINITY;
         } else if (!Double.isFinite(q)) { /* q == +Inf */
diff --git a/com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/stats/LogNormal.java b/com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/stats/LogNormal.java
index 824a4acef8f241ac6d5d34f358f970ce727e15a7..9384ad65764f5da59ad03f14d87e0b8ba1368d1c 100644
--- a/com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/stats/LogNormal.java
+++ b/com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/stats/LogNormal.java
@@ -23,15 +23,15 @@ public final class LogNormal {
         // only static members
     }
 
-    public static final class RLNorm implements RandFunction2_Double {
+    public static final class RLNorm extends RandFunction2_Double {
         private final Rnorm rnorm = new Rnorm();
 
         @Override
-        public double evaluate(double meanlog, double sdlog, RandomNumberProvider rand) {
+        public double execute(double meanlog, double sdlog, RandomNumberProvider rand) {
             if (Double.isNaN(meanlog) || !Double.isFinite(sdlog) || sdlog < 0.) {
-                return RMath.mlError();
+                return RMathError.defaultError();
             }
-            return Math.exp(rnorm.evaluate(meanlog, sdlog, rand));
+            return Math.exp(rnorm.execute(meanlog, sdlog, rand));
         }
     }
 
@@ -43,7 +43,7 @@ public final class LogNormal {
             }
             if (sdlog <= 0) {
                 if (sdlog < 0) {
-                    return RMath.mlError();
+                    return RMathError.defaultError();
                 }
                 // sdlog == 0 :
                 return (Math.log(x) == meanlog) ? Double.POSITIVE_INFINITY : DPQ.rd0(giveLog);
@@ -84,7 +84,7 @@ public final class LogNormal {
                 return x + meanlog + sdlog;
             }
             if (sdlog < 0) {
-                return RMath.mlError();
+                return RMathError.defaultError();
             }
             if (x > 0) {
                 return pnorm.evaluate(Math.log(x), meanlog, sdlog, lowerTail, logP);
diff --git a/com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/stats/Logis.java b/com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/stats/Logis.java
new file mode 100644
index 0000000000000000000000000000000000000000..b810fbae9f35275e8b574f23c3dfd7c8ac127714
--- /dev/null
+++ b/com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/stats/Logis.java
@@ -0,0 +1,138 @@
+/*
+ * This material is distributed under the GNU General Public License
+ * Version 2. You may review the terms of this license at
+ * http://www.gnu.org/licenses/gpl-2.0.html
+ *
+ * Copyright (C) 1998 Ross Ihaka
+ * Copyright (c) 1998--2008, The R Core Team
+ * Copyright (c) 2016, 2016, Oracle and/or its affiliates
+ *
+ * All rights reserved.
+ */
+/*
+ *  Copyright (C) 1995, 1996    Robert Gentleman and Ross Ihaka
+ *  Copyright (C) 2000          The R Core Team
+ */
+package com.oracle.truffle.r.library.stats;
+
+import com.oracle.truffle.r.library.stats.DPQ.EarlyReturn;
+import com.oracle.truffle.r.library.stats.RandGenerationFunctions.RandFunction2_Double;
+import com.oracle.truffle.r.library.stats.RandGenerationFunctions.RandomNumberProvider;
+import com.oracle.truffle.r.library.stats.StatsFunctions.Function3_1;
+import com.oracle.truffle.r.library.stats.StatsFunctions.Function3_2;
+
+public final class Logis {
+    private Logis() {
+        // only static members
+    }
+
+    public static final class DLogis implements Function3_1 {
+        @Override
+        public double evaluate(double xIn, double location, double scale, boolean giveLog) {
+            if (Double.isNaN(xIn) || Double.isNaN(location) || Double.isNaN(scale)) {
+                return xIn + location + scale;
+            }
+            if (scale <= 0.0) {
+                return RMathError.defaultError();
+            }
+
+            double x = TOMS708.fabs((xIn - location) / scale);
+            double e = Math.exp(-x);
+            double f = 1.0 + e;
+            return giveLog ? -(x + Math.log(scale * f * f)) : e / (scale * f * f);
+        }
+    }
+
+    public static final class QLogis implements Function3_2 {
+        @Override
+        public double evaluate(double p, double location, double scale, boolean lowerTail, boolean logP) {
+            if (Double.isNaN(p) || Double.isNaN(location) || Double.isNaN(scale)) {
+                return p + location + scale;
+            }
+
+            try {
+                DPQ.rqp01boundaries(p, Double.NEGATIVE_INFINITY, Double.POSITIVE_INFINITY, lowerTail, logP);
+            } catch (EarlyReturn e) {
+                return e.result;
+            }
+
+            if (scale < 0.) {
+                return RMathError.defaultError();
+            }
+            if (scale == 0.) {
+                return location;
+            }
+
+            /* p := logit(p) = Math.log( p / (1-p) ) : */
+            double newP;
+            if (logP) {
+                if (lowerTail) {
+                    newP = p - DPQ.rlog1exp(p);
+                } else {
+                    newP = DPQ.rlog1exp(p) - p;
+                }
+            } else {
+                newP = Math.log(lowerTail ? (p / (1. - p)) : ((1. - p) / p));
+            }
+
+            return location + scale * newP;
+        }
+    }
+
+    public static final class PLogis implements Function3_2 {
+        @Override
+        public double evaluate(double xIn, double location, double scale, boolean lowerTail, boolean logP) {
+            if (Double.isNaN(xIn) || Double.isNaN(location) || Double.isNaN(scale)) {
+                return xIn + location + scale;
+            }
+            if (scale <= 0.0) {
+                return RMathError.defaultError();
+            }
+
+            double x = (xIn - location) / scale;
+            if (Double.isNaN(x)) {
+                return RMathError.defaultError();
+            }
+
+            try {
+                DPQ.rpboundsinf01(x, lowerTail, logP);
+            } catch (EarlyReturn earlyReturn) {
+                return earlyReturn.result;
+            }
+
+            if (logP) {
+                // Math.log(1 / (1 + Math.exp( +- x ))) = -Math.log(1 + Math.exp( +- x))
+                return -log1pexp(lowerTail ? -x : x);
+            } else {
+                return 1 / (1 + Math.exp(lowerTail ? -x : x));
+            }
+        }
+
+        private static double log1pexp(double x) {
+            if (x <= 18.) {
+                return RMath.log1p(Math.exp(x));
+            }
+            if (x > 33.3) {
+                return x;
+            }
+            // else: 18.0 < x <= 33.3 :
+            return x + Math.exp(-x);
+        }
+    }
+
+    public static final class RLogis extends RandFunction2_Double {
+        @Override
+        public double execute(double location, double scale, RandomNumberProvider rand) {
+            if (Double.isNaN(location) || !Double.isFinite(scale)) {
+                return RMathError.defaultError();
+            }
+
+            if (scale == 0. || !Double.isFinite(location)) {
+                return location;
+            } else {
+                double u = rand.unifRand();
+                return location + scale * Math.log(u / (1. - u));
+            }
+        }
+    }
+}
diff --git a/com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/stats/MathConstants.java b/com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/stats/MathConstants.java
index 0885fbeecf503bb056f1c289b3c2096f5ef3e5a3..d7c4b92c6220ba622018eb086fa0db0d3763d38b 100644
--- a/com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/stats/MathConstants.java
+++ b/com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/stats/MathConstants.java
@@ -86,6 +86,15 @@ public final class MathConstants {
 
     public static final double DBL_EPSILON = Math.ulp(1.0);
 
+    public static final double ML_NAN = Double.NaN;
+
+    // Different to Double.MIN_VALUE!
+    public static final double DBL_MIN = Double.MIN_NORMAL;
+
+    public static final double DBL_MAX = Double.MAX_VALUE;
+
+    static final double INV_SQRT_2_PI = .398942280401433; /* == 1/sqrt(2*pi); */
+
     /**
      * Compute the log of a sum from logs of terms, i.e.,
      *
@@ -97,11 +106,4 @@ public final class MathConstants {
     public static double logspaceAdd(double logx, double logy) {
         return Math.max(logx, logy) + Math.log1p(Math.exp(-Math.abs(logx - logy)));
     }
-
-    // R_forceint
-    public static double forceint(double x) {
-        // Note: in GnuR this is alias for nearbyint, which may not behave exactly like Math.round,
-        // especially Math.round(-0.5) == 0.0, instead of -0.0, does it matter a lot?
-        return Double.isFinite(x) ? Math.round(x) : x;
-    }
 }
diff --git a/com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/stats/MathInit.java b/com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/stats/MathInit.java
index 697faaac42e7a0df622a9b71598b4950cf380e49..b9cad15bb0979abb0be288b508b1b435f4077693 100644
--- a/com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/stats/MathInit.java
+++ b/com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/stats/MathInit.java
@@ -10,6 +10,7 @@
  */
 package com.oracle.truffle.r.library.stats;
 
+import static com.oracle.truffle.r.library.stats.MathConstants.DBL_MIN;
 import static com.oracle.truffle.r.library.stats.MathConstants.M_LOG10_2;
 
 import com.oracle.truffle.r.runtime.RInternalError;
@@ -26,7 +27,7 @@ public final class MathInit {
     public static double d1mach(int i) {
         switch (i) {
             case 1:
-                return Double.MIN_VALUE;
+                return DBL_MIN;
             case 2:
                 return Double.MAX_VALUE;
             case 3:
diff --git a/com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/stats/PGamma.java b/com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/stats/PGamma.java
new file mode 100644
index 0000000000000000000000000000000000000000..5886a01b16ae9cf1c6e7ae0f0a9fb72f194d8b1f
--- /dev/null
+++ b/com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/stats/PGamma.java
@@ -0,0 +1,38 @@
+/*
+ * This material is distributed under the GNU General Public License
+ * Version 2. You may review the terms of this license at
+ * http://www.gnu.org/licenses/gpl-2.0.html
+ *
+ * Copyright (C) 2005-6 Morten Welinder <terra@gnome.org>
+ * Copyright (C) 2005-10 The R Foundation
+ * Copyright (C) 2006-2015 The R Core Team
+ * Copyright (c) 2016, Oracle and/or its affiliates
+ *
+ * All rights reserved.
+ */
+package com.oracle.truffle.r.library.stats;
+
+import static com.oracle.truffle.r.library.stats.GammaFunctions.pgammaRaw;
+
+import com.oracle.truffle.r.library.stats.StatsFunctions.Function3_2;
+
+public final class PGamma implements Function3_2 {
+    @Override
+    public double evaluate(double xIn, double alph, double scale, boolean lowerTail, boolean logP) {
+        if (Double.isNaN(xIn) || Double.isNaN(alph) || Double.isNaN(scale)) {
+            return xIn + alph + scale;
+        }
+        if (alph < 0 || scale < 0) {
+            return RMathError.defaultError();
+        }
+
+        double x = xIn / scale;
+        if (Double.isNaN(x)) {
+            return x;
+        }
+        if (alph == 0.) {
+            return x <= 0 ? DPQ.rdt0(lowerTail, logP) : DPQ.rdt1(lowerTail, logP);
+        }
+        return pgammaRaw(x, alph, lowerTail, logP);
+    }
+}
diff --git a/com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/stats/PHyper.java b/com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/stats/PHyper.java
new file mode 100644
index 0000000000000000000000000000000000000000..5a6922a91a1ae2e6f0af36d53bfbb8409d1be409
--- /dev/null
+++ b/com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/stats/PHyper.java
@@ -0,0 +1,95 @@
+/*
+ * This material is distributed under the GNU General Public License
+ * Version 2. You may review the terms of this license at
+ * http://www.gnu.org/licenses/gpl-2.0.html
+ *
+ * Copyright (C) 1998 Ross Ihaka
+ * Copyright (c) 1999-2014, The R Core Team
+ * Copyright (c) 2004, The R Foundation
+ * Copyright (c) 2016, Oracle and/or its affiliates
+ *
+ * All rights reserved.
+ */
+/*
+ * Copyright (C) 2004 Morten Welinder
+ *
+ * Current implementation based on posting
+ * From: Morten Welinder <terra@gnome.org>
+ * Cc: R-bugs@biostat.ku.dk
+ * Subject: [Rd] phyper accuracy and efficiency (PR#6772)
+ * Date: Thu, 15 Apr 2004 18:06:37 +0200 (CEST)
+ */
+package com.oracle.truffle.r.library.stats;
+
+import static com.oracle.truffle.r.library.stats.MathConstants.DBL_EPSILON;
+
+import com.oracle.truffle.r.library.stats.StatsFunctions.Function4_2;
+
+public final class PHyper implements Function4_2 {
+    private final DHyper dhyper = new DHyper();
+
+    @Override
+    public double evaluate(double xIn, double nrIn, double nbIn, double nIn, boolean lowerTailIn, boolean logP) {
+        /* Sample of n balls from nr red and nb black ones; x are red */
+        if (Double.isNaN(xIn) || Double.isNaN(nrIn) || Double.isNaN(nbIn) || Double.isNaN(nIn)) {
+            return xIn + nrIn + nbIn + nIn;
+        }
+
+        double x = Math.floor(xIn + 1e-7);
+        double nr = RMath.forceint(nrIn);
+        double nb = RMath.forceint(nbIn);
+        double n = RMath.forceint(nIn);
+
+        if (nr < 0 || nb < 0 || !Double.isFinite(nr + nb) || n < 0 || n > nr + nb) {
+            return RMathError.defaultError();
+        }
+
+        boolean lowerTail = lowerTailIn;
+        if (x * (nr + nb) > n * nr) {
+            /* Swap tails. */
+            double oldNB = nb;
+            nb = nr;
+            nr = oldNB;
+            x = n - x - 1;
+            lowerTail = !lowerTail;
+        }
+
+        if (x < 0) {
+            return DPQ.rdt0(lowerTail, logP);
+        }
+        if (x >= nr || x >= n) {
+            return DPQ.rdt1(lowerTail, logP);
+        }
+
+        double d = dhyper.evaluate(x, nr, nb, n, logP);
+        double pd = pdhyper(x, nr, nb, n, logP);
+
+        return logP ? DPQ.rdtlog(d + pd, lowerTail, logP) : DPQ.rdlval(d * pd, lowerTail);
+    }
+
+    static double pdhyper(double xIn, double nr, double nb, double n, boolean logP) {
+        /*
+         * Calculate
+         *
+         * phyper (x, nr, nb, n, true, false) [log] ---------------------------------- dhyper (x,
+         * nr, nb, n, false)
+         *
+         * without actually calling phyper. This assumes that
+         *
+         * x * (nr + nb) <= n * nr
+         *
+         */
+        /* LDOUBLE */double sum = 0;
+        /* LDOUBLE */double term = 1;
+
+        double x = xIn;
+        while (x > 0 && term >= DBL_EPSILON * sum) {
+            term *= x * (nb - n + x) / (n + 1 - x) / (nr + 1 - x);
+            sum += term;
+            x--;
+        }
+
+        double ss = sum;
+        return logP ? RMath.log1p(ss) : 1 + ss;
+    }
+}
diff --git a/com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/stats/PNBeta.java b/com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/stats/PNBeta.java
new file mode 100644
index 0000000000000000000000000000000000000000..012c7b2b16d0878f6b2128d164f3c7313b1d370a
--- /dev/null
+++ b/com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/stats/PNBeta.java
@@ -0,0 +1,126 @@
+/*
+ * This material is distributed under the GNU General Public License
+ * Version 2. You may review the terms of this license at
+ * http://www.gnu.org/licenses/gpl-2.0.html
+ *
+ * Copyright (c) 2000-2013, The R Core Team
+ * Copyright (c) 2016, Oracle and/or its affiliates
+ *
+ * All rights reserved.
+ */
+package com.oracle.truffle.r.library.stats;
+
+import static com.oracle.truffle.r.library.stats.GammaFunctions.lgammafn;
+
+import com.oracle.truffle.r.library.stats.DPQ.EarlyReturn;
+import com.oracle.truffle.r.library.stats.RMathError.MLError;
+import com.oracle.truffle.r.library.stats.StatsFunctions.Function4_2;
+import com.oracle.truffle.r.library.stats.TOMS708.Bratio;
+
+public final class PNBeta implements Function4_2 {
+    @Override
+    public double evaluate(double x, double a, double b, double ncp, boolean lowerTail, boolean logP) {
+        if (Double.isNaN(x) || Double.isNaN(a) || Double.isNaN(b) || Double.isNaN(ncp)) {
+            return x + a + b + ncp;
+        }
+        try {
+            DPQ.rpbounds01(x, 0., 1., lowerTail, logP);
+        } catch (EarlyReturn e) {
+            return e.result;
+        }
+        return pnbeta2(x, 1 - x, a, b, ncp, lowerTail, logP);
+    }
+
+    double pnbeta2(double x, double oX, double a, double b, double ncp, boolean lowerTail, boolean logP) {
+        /* LDOUBLE */
+        double ans = pnbetaRaw(x, oX, a, b, ncp);
+
+        /* return DPQ.rdtval(ans), but we want to warn about cancellation here */
+        if (lowerTail) {
+            // #ifdef HAVE_LONG_DOUBLE
+            // return (double) (logP ? logl(ans) : ans);
+            // #else
+            return logP ? Math.log(ans) : ans;
+        } else {
+            if (ans > 1. - 1e-10) {
+                RMathError.error(MLError.PRECISION, "pnbeta");
+            }
+            if (ans > 1.0) {
+                ans = 1.0;
+            } /* Precaution */
+            // #if defined(HAVE_LONG_DOUBLE) && defined(HAVE_LOG1PL)
+            // return (double) (logP ? log1pl(-ans) : (1. - ans));
+            // #else
+            /* include standalone case */
+            return (logP ? RMath.log1p(-ans) : (1. - ans));
+        }
+
+    }
+
+    /*
+     * GnuR: change errmax and itrmax if desired; original (AS 226, R84) had (errmax; itrmax) =
+     * (1e-6; 100)
+     */
+    private static final double errmax = 1.0e-9;
+    private static final int itrmax = 10000; /*
+                                              * GnuR: 100 is not enough for pf(ncp=200) see PR#11277
+                                              */
+
+    double pnbetaRaw(double x, double oX, double a, double b, double ncp) {
+        /* oX == 1 - x but maybe more accurate */
+        if (ncp < 0. || a <= 0. || b <= 0.) {
+            return RMathError.defaultError();
+        }
+
+        if (x < 0. || oX > 1. || (x == 0. && oX == 1.)) {
+            return 0.;
+        }
+        if (x > 1. || oX < 0. || (x == 1. && oX == 0.)) {
+            return 1.;
+        }
+
+        double c = ncp / 2.;
+
+        /* initialize the series */
+        double x0 = Math.floor(RMath.fmax2(c - 7. * Math.sqrt(c), 0.));
+        double a0 = a + x0;
+        double lbeta = lgammafn(a0) + lgammafn(b) - lgammafn(a0 + b);
+
+        /* temp = pbeta_raw(x, a0, b, true, false), but using (x, oX): */
+        double temp = Bratio.bratio(a0, b, x, oX, false).w;
+
+        /* LDOUBLE */double gx = Math.exp(a0 * Math.log(x) + b * (x < .5 ? RMath.log1p(-x) : Math.log(oX)) - lbeta - Math.log(a0));
+        /* LDOUBLE */double q;
+        if (a0 > a) {
+            q = Math.exp(-c + x0 * Math.log(c) - lgammafn(x0 + 1.));
+        } else {
+            q = Math.exp(-c);
+        }
+
+        /* LDOUBLE */double sumq = 1. - q;
+        /* LDOUBLE */double ans = q * temp;
+        /* LDOUBLE */double ax;
+
+        /* recurse over subsequent terms until convergence is achieved */
+        double j = Math.floor(x0); // x0 could be billions, and is in package EnvStats
+        double errbd;
+        do {
+            j++;
+            temp -= gx;
+            gx *= x * (a + b + j - 1.) / (a + j);
+            q *= c / j;
+            sumq -= q;
+            ax = temp * q;
+            ans += ax;
+            errbd = ((temp - gx) * sumq);
+        } while (errbd > errmax && j < itrmax + x0);
+
+        if (errbd > errmax) {
+            RMathError.error(MLError.PRECISION, "pnbeta");
+        }
+        if (j >= itrmax + x0) {
+            RMathError.error(MLError.NOCONV, "pnbeta");
+        }
+        return ans;
+    }
+}
diff --git a/com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/stats/PNChisq.java b/com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/stats/PNChisq.java
new file mode 100644
index 0000000000000000000000000000000000000000..c776e2c447895032b09072188ef2f05d050d5db4
--- /dev/null
+++ b/com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/stats/PNChisq.java
@@ -0,0 +1,308 @@
+/*
+ * This material is distributed under the GNU General Public License
+ * Version 2. You may review the terms of this license at
+ * http://www.gnu.org/licenses/gpl-2.0.html
+ *
+ * Copyright (c) 2000-2015, The R Core Team
+ * Copyright (c) 2003-2015, The R Foundation
+ * Copyright (c) 2016, Oracle and/or its affiliates
+ *
+ * All rights reserved.
+ */
+/*
+ *  Algorithm AS 275 Appl.Statist. (1992), vol.41, no.2
+ *  original  (C) 1992       Royal Statistical Society
+ *
+ *  Computes the noncentral chi-squared distribution function with
+ *  positive real degrees of freedom df and nonnegative noncentrality
+ *  parameter ncp.  pnchisq_raw is based on
+ *
+ *    Ding, C. G. (1992)
+ *    Algorithm AS275: Computing the non-central chi-squared
+ *    distribution function. Appl.Statist., 41, 478-482.
+ */
+
+package com.oracle.truffle.r.library.stats;
+
+import static com.oracle.truffle.r.library.stats.GammaFunctions.lgamma;
+import static com.oracle.truffle.r.library.stats.GammaFunctions.lgammafn;
+import static com.oracle.truffle.r.library.stats.MathConstants.DBL_EPSILON;
+import static com.oracle.truffle.r.library.stats.MathConstants.DBL_MIN_EXP;
+import static com.oracle.truffle.r.library.stats.MathConstants.M_LN10;
+import static com.oracle.truffle.r.library.stats.MathConstants.M_LN2;
+import static com.oracle.truffle.r.library.stats.MathConstants.M_LN_SQRT_2PI;
+import static com.oracle.truffle.r.library.stats.MathConstants.logspaceAdd;
+
+import com.oracle.truffle.r.library.stats.Chisq.PChisq;
+import com.oracle.truffle.r.library.stats.RMathError.MLError;
+import com.oracle.truffle.r.library.stats.StatsFunctions.Function3_2;
+import com.oracle.truffle.r.runtime.RError.Message;
+
+public final class PNChisq implements Function3_2 {
+    private static final double _dbl_min_exp = M_LN2 * DBL_MIN_EXP;
+    private final PChisq pchisq = new PChisq();
+
+    @Override
+    public double evaluate(double x, double df, double ncp, boolean lowerTail, boolean logP) {
+        double ans;
+        if (Double.isNaN(x) || Double.isNaN(df) || Double.isNaN(ncp)) {
+            return x + df + ncp;
+        }
+        if (!Double.isFinite(df) || !Double.isFinite(ncp)) {
+            return RMathError.defaultError();
+        }
+
+        if (df < 0. || ncp < 0.) {
+            return RMathError.defaultError();
+        }
+
+        ans = pnchisqRaw(x, df, ncp, 1e-12, 8 * DBL_EPSILON, 1000000, lowerTail, logP);
+        if (ncp >= 80) {
+            if (lowerTail) {
+                ans = RMath.fmin2(ans, DPQ.rd1(logP)); /* e.g., pchisq(555, 1.01, ncp = 80) */
+            } else { /* !lower_tail */
+                /* since we computed the other tail cancellation is likely */
+                if (ans < (logP ? (-10. * M_LN10) : 1e-10)) {
+                    RMathError.error(MLError.PRECISION, "pnchisq");
+                }
+                if (!logP) {
+                    ans = RMath.fmax2(ans, 0.0);
+                } /* Precaution PR#7099 */
+            }
+        }
+        if (!logP || ans < -1e-8) {
+            return ans;
+        } else { // log_p && ans > -1e-8
+            // prob. = Math.exp(ans) is near one: we can do better using the other tail
+            debugPrintf("   pnchisq_raw(*, log_p): ans=%g => 2nd call, other tail\n", ans);
+            // GNUR fix me: (sum,sum2) will be the same (=> return them as well and reuse here ?)
+            ans = pnchisqRaw(x, df, ncp, 1e-12, 8 * DBL_EPSILON, 1000000, !lowerTail, false);
+            return RMath.log1p(-ans);
+        }
+    }
+
+    double pnchisqRaw(double x, double f, double theta /* = ncp */,
+                    double errmax, double reltol, int itrmax,
+                    boolean lowerTail, boolean logP) {
+        if (x <= 0.) {
+            if (x == 0. && f == 0.) {
+                final double minusLambda = (-0.5 * theta);
+                return lowerTail ? DPQ.rdexp(minusLambda, logP) : (logP ? DPQ.rlog1exp(minusLambda) : -RMath.expm1(minusLambda));
+            }
+            /* x < 0 or {x==0, f > 0} */
+            return DPQ.rdt0(lowerTail, logP);
+        }
+        if (!Double.isFinite(x)) {
+            return DPQ.rdt1(lowerTail, logP);
+        }
+
+        if (theta < 80) {
+            /* use 110 for Inf, as ppois(110, 80/2, lower.tail=false) is 2e-20 */
+            return smallTheta(x, f, theta, lowerTail, logP);
+        }
+
+        // else: theta == ncp >= 80 --------------------------------------------
+        debugPrintf("pnchisq(x=%g, f=%g, theta=%g >= 80): ", x, f, theta);
+
+        // Series expansion ------- FIXME: log_p=true, lower_tail=false only applied at end
+
+        double lam = .5 * theta;
+        boolean lamSml = (-lam < _dbl_min_exp);
+        double lLam = -1;
+        /* LDOUBLE */double lu = -1;
+        /* LDOUBLE */double u;
+        if (lamSml) {
+            u = 0;
+            lu = -lam; /* == ln(u) */
+            lLam = Math.log(lam);
+        } else {
+            u = Math.exp(-lam);
+        }
+
+        /* evaluate the first term */
+        /* LDOUBLE */double v = u;
+        double x2 = .5 * x;
+        double f2 = .5 * f;
+        double fx2n = f - x;
+
+        debugPrintf("-- v=Math.exp(-th/2)=%g, x/2= %g, f/2= %g\n", v, x2, f2);
+
+        /* LDOUBLE */double lt;
+        /* LDOUBLE */double t;
+        if (f2 * DBL_EPSILON > 0.125 && /* very large f and x ~= f: probably needs */
+                        MathWrapper.abs(t = x2 - f2) < /* another algorithm anyway */
+                        Math.sqrt(DBL_EPSILON) * f2) {
+            /* evade cancellation error */
+            /* t = Math.exp((1 - t)*(2 - t/(f2 + 1))) / Math.sqrt(2*M_PI*(f2 + 1)); */
+            lt = (1 - t) * (2 - t / (f2 + 1)) - M_LN_SQRT_2PI - 0.5 * Math.log(f2 + 1);
+            debugPrintf(" (case I) ==> ");
+        } else {
+            /* Usual case 2: careful not to overflow .. : */
+            lt = f2 * Math.log(x2) - x2 - lgammafn(f2 + 1);
+        }
+        debugPrintf(" lt= %g", lt);
+
+        boolean tSml = (lt < _dbl_min_exp);
+        double lX = -1;
+        double term;
+        /* LDOUBLE */double ans;
+        if (tSml) {
+            debugPrintf(" is very small\n");
+            if (x > f + theta + 5 * Math.sqrt(2 * (f + 2 * theta))) {
+                /* x > E[X] + 5* sigma(X) */
+                return DPQ.rdt1(lowerTail, logP); /*
+                                                   * GNUR fix me: could be more accurate than 0.
+                                                   */
+            } /* else */
+            lX = Math.log(x);
+            ans = term = 0.;
+            t = 0;
+        } else {
+            t = MathWrapper.exp(lt);
+            debugPrintf(", t=Math.exp(lt)= %g\n", t);
+            ans = term = (v * t);
+        }
+
+        int n;
+        double f2n;
+        boolean isIt;
+        double bound;
+        for (n = 1, f2n = f + 2., fx2n += 2.;; n++, f2n += 2, fx2n += 2) {
+            debugPrintf("\n _OL_: n=%d", n);
+            /*
+             * f2n === f + 2*n fx2n === f - x + 2*n > 0 <==> (f+2n) > x
+             */
+            if (fx2n > 0) {
+                /* find the error bound and check for convergence */
+                bound = t * x / fx2n;
+                debugPrintf("\n L10: n=%d; term= %g; bound= %g", n, term, bound);
+                boolean isR = isIt = false;
+                boolean isB;
+                /* convergence only if BOTH absolute and relative error < 'bnd' */
+                if (((isB = (bound <= errmax)) &&
+                                (isR = (term <= reltol * ans))) || (isIt = (n > itrmax))) {
+                    debugPrintf("BREAK n=%d %s; bound= %g %s, rel.err= %g %s\n",
+                                    n, (isIt ? "> itrmax" : ""),
+                                    bound, (isB ? "<= errmax" : ""),
+                                    term / ans, (isR ? "<= reltol" : ""));
+                    break; /* out completely */
+                }
+
+            }
+
+            /* evaluate the next term of the */
+            /* expansion and then the partial sum */
+
+            if (lamSml) {
+                lu += lLam - Math.log(n); /* u = u* lam / n */
+                if (lu >= _dbl_min_exp) {
+                    /* no underflow anymore ==> change regime */
+                    debugPrintf(" n=%d; nomore underflow in u = Math.exp(lu) ==> change\n",
+                                    n);
+                    v = u = MathWrapper.exp(lu); /* the first non-0 'u' */
+                    lamSml = false;
+                }
+            } else {
+                u *= lam / n;
+                v += u;
+            }
+            if (tSml) {
+                lt += lX - Math.log(f2n); /* t <- t * (x / f2n) */
+                if (lt >= _dbl_min_exp) {
+                    /* no underflow anymore ==> change regime */
+                    debugPrintf("  n=%d; nomore underflow in t = Math.exp(lt) ==> change\n", n);
+                    t = MathWrapper.exp(lt); /* the first non-0 't' */
+                    tSml = false;
+                }
+            } else {
+                t *= x / f2n;
+            }
+            if (!lamSml && !tSml) {
+                term = v * t;
+                ans += term;
+            }
+
+        } /* for(n ...) */
+
+        if (isIt) {
+            RMathError.warning(Message.PCHISQ_NOT_CONVERGED_WARNING, x, itrmax);
+        }
+
+        debugPrintf("\n == L_End: n=%d; term= %g; bound=%g\n", n, term, bound);
+        return DPQ.rdtval(ans, lowerTail, logP);
+    }
+
+    private double smallTheta(double x, double f, double theta, boolean lowerTail, boolean logP) {
+        // Have pgamma(x,s) < x^s / Gamma(s+1) (< and ~= for small x)
+        // ==> pchisq(x, f) = pgamma(x, f/2, 2) = pgamma(x/2, f/2)
+        // < (x/2)^(f/2) / Gamma(f/2+1) < eps
+        // <==> f/2 * Math.log(x/2) - Math.log(Gamma(f/2+1)) < Math.log(eps) ( ~= -708.3964 )
+        // <==> Math.log(x/2) < 2/f*(Math.log(Gamma(f/2+1)) + Math.log(eps))
+        // <==> Math.log(x) < Math.log(2) + 2/f*(Math.log(Gamma(f/2+1)) + Math.log(eps))
+        if (lowerTail && f > 0. && Math.log(x) < M_LN2 + 2 / f * (lgamma(f / 2. + 1) + _dbl_min_exp)) {
+            // all pchisq(x, f+2*i, lower_tail, false), i=0,...,110 would underflow to 0.
+            // ==> work in log scale
+            double lambda = 0.5 * theta;
+            double sum;
+            double sum2;
+            double pr = -lambda;
+            sum = sum2 = Double.NEGATIVE_INFINITY;
+            /* we need to renormalize here: the result could be very close to 1 */
+            int i;
+            for (i = 0; i < 110; pr += Math.log(lambda) - Math.log(++i)) {
+                sum2 = logspaceAdd(sum2, pr);
+                sum = logspaceAdd(sum, pr + pchisq.evaluate(x, f + 2 * i, lowerTail, true));
+                if (sum2 >= -1e-15) {
+                    /* <=> EXP(sum2) >= 1-1e-15 */ break;
+                }
+            }
+            /* LDOUBLE */double ans = sum - sum2;
+            debugPrintf("pnchisq(x=%g, f=%g, th.=%g); th. < 80, logspace: i=%d, ans=(sum=%g)-(sum2=%g)\n",
+                            x, f, theta, i, sum, sum2);
+            return logP ? ans : MathWrapper.exp(ans);
+        } else {
+            /* LDOUBLE */double lambda = 0.5 * theta;
+            /* LDOUBLE */double sum = 0;
+            /* LDOUBLE */double sum2 = 0;
+            /* LDOUBLE */double pr = Math.exp(-lambda); // does this need a feature test?
+            /* we need to renormalize here: the result could be very close to 1 */
+            int i;
+            for (i = 0; i < 110; pr *= lambda / ++i) {
+                // pr == Math.exp(-lambda) lambda^i / i! == dpois(i, lambda)
+                sum2 += pr;
+                // pchisq(*, i, *) is strictly decreasing to 0 for lower_tail=true
+                // and strictly increasing to 1 for lower_tail=false
+                sum += pr * pchisq.evaluate(x, f + 2 * i, lowerTail, false);
+                if (sum2 >= 1 - 1e-15) {
+                    break;
+                }
+            }
+            /* LDOUBLE */double ans = sum / sum2;
+            debugPrintf("pnchisq(x=%g, f=%g, theta=%g); theta < 80: i=%d, sum=%g, sum2=%g\n",
+                            x, f, theta, i, sum, sum2);
+            return logP ? MathWrapper.log(ans) : ans;
+        }
+    }
+
+    @SuppressWarnings("unused")
+    private void debugPrintf(String fmt, Object... args) {
+        // System.out.printf(fmt + "\n", args);
+    }
+
+    /**
+     * For easier switch to {@code Decimal} if necessary.
+     */
+    private static final class MathWrapper {
+        public static double exp(double x) {
+            return Math.exp(x);
+        }
+
+        public static double log(double x) {
+            return Math.log(x);
+        }
+
+        public static double abs(double x) {
+            return Math.abs(x);
+        }
+    }
+}
diff --git a/com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/stats/PPois.java b/com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/stats/PPois.java
new file mode 100644
index 0000000000000000000000000000000000000000..1ad3492f1ffb50c308b4f932f294dfc9bcd34c3f
--- /dev/null
+++ b/com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/stats/PPois.java
@@ -0,0 +1,37 @@
+/*
+ * This material is distributed under the GNU General Public License
+ * Version 2. You may review the terms of this license at
+ * http://www.gnu.org/licenses/gpl-2.0.html
+ *
+ * Copyright (C) 1998 Ross Ihaka
+ * Copyright (c) 2000, The R Core Team
+ * Copyright (c) 2016, Oracle and/or its affiliates
+ *
+ * All rights reserved.
+ */
+package com.oracle.truffle.r.library.stats;
+
+import static com.oracle.truffle.r.library.stats.GammaFunctions.pgamma;
+
+import com.oracle.truffle.r.library.stats.StatsFunctions.Function2_2;
+
+public final class PPois implements Function2_2 {
+    @Override
+    public double evaluate(double x, double lambda, boolean lowerTail, boolean logP) {
+        if (Double.isNaN(x) || Double.isNaN(lambda) || lambda < 0.) {
+            return RMathError.defaultError();
+        }
+        if (x < 0) {
+            return DPQ.rdt0(lowerTail, logP);
+        }
+        if (lambda == 0.) {
+            return DPQ.rdt1(lowerTail, logP);
+        }
+        if (!Double.isFinite(x)) {
+            return DPQ.rdt1(lowerTail, logP);
+        }
+        double floorX = Math.floor(x + 1e-7);
+
+        return pgamma(lambda, floorX + 1, 1., !lowerTail, logP);
+    }
+}
diff --git a/com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/stats/Pbeta.java b/com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/stats/Pbeta.java
index 02c713c68abadf8fe6755b5a2ead937269cc88bd..4c12e76f64cc9dc11324231c7a825de34b62abb3 100644
--- a/com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/stats/Pbeta.java
+++ b/com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/stats/Pbeta.java
@@ -29,7 +29,7 @@ public final class Pbeta implements Function3_2 {
     }
 
     @TruffleBoundary
-    private static double pbetaRaw(double x, double a, double b, boolean lowerTail, boolean logProb) {
+    static double pbetaRaw(double x, double a, double b, boolean lowerTail, boolean logProb) {
         // treat limit cases correctly here:
         if (a == 0 || b == 0 || !Double.isFinite(a) || !Double.isFinite(b)) {
             // NB: 0 < x < 1 :
diff --git a/com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/stats/Pbinom.java b/com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/stats/Pbinom.java
index 70fcce282db80d30395effba2881a35c155aafcb..f0b796a8845cbe61675befeedf7e13c6dc026cc1 100644
--- a/com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/stats/Pbinom.java
+++ b/com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/stats/Pbinom.java
@@ -34,9 +34,9 @@ public final class Pbinom implements StatsFunctions.Function3_2 {
         if (DPQ.nonint(size)) {
             nanProfile.enter();
             DPQ.nointCheckWarning(size, "n");
-            return DPQ.rd0(logP);
+            return RMathError.defaultError();
         }
-        size = Math.round(size);
+        size = RMath.forceint(size);
         /* PR#8560: n=0 is a valid value */
         if (size < 0 || prob < 0 || prob > 1) {
             nanProfile.enter();
diff --git a/com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/stats/Pnf.java b/com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/stats/Pnf.java
new file mode 100644
index 0000000000000000000000000000000000000000..a48d487b9d972af9bb63f87a42f635fa67e2352e
--- /dev/null
+++ b/com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/stats/Pnf.java
@@ -0,0 +1,54 @@
+/*
+ * This material is distributed under the GNU General Public License
+ * Version 2. You may review the terms of this license at
+ * http://www.gnu.org/licenses/gpl-2.0.html
+ *
+ * Copyright (C) 1998 Ross Ihaka
+ * Copyright (c) 2000-2008, The R Core Team
+ * Copyright (c) 2016, Oracle and/or its affiliates
+ *
+ * All rights reserved.
+ */
+package com.oracle.truffle.r.library.stats;
+
+import com.oracle.truffle.r.library.stats.DPQ.EarlyReturn;
+import com.oracle.truffle.r.library.stats.StatsFunctions.Function4_2;
+
+public final class Pnf implements Function4_2 {
+    private final PNChisq pnchisq = new PNChisq();
+    private final PNBeta pnbeta = new PNBeta();
+
+    @Override
+    public double evaluate(double x, double df1, double df2, double ncp, boolean lowerTail, boolean logP) {
+        double y;
+        if (Double.isNaN(x) || Double.isNaN(df1) || Double.isNaN(df2) || Double.isNaN(ncp)) {
+            return x + df2 + df1 + ncp;
+        }
+        if (df1 <= 0. || df2 <= 0. || ncp < 0) {
+            return RMathError.defaultError();
+        }
+        if (!Double.isFinite(ncp)) {
+
+            return RMathError.defaultError();
+        }
+        if (!Double.isFinite(df1) && !Double.isFinite(df2)) {
+            /* both +Inf */
+            return RMathError.defaultError();
+        }
+
+        try {
+            DPQ.rpbounds01(x, 0., Double.POSITIVE_INFINITY, lowerTail, logP);
+        } catch (EarlyReturn e) {
+            return e.result;
+        }
+
+        if (df2 > 1e8) {
+            /* avoid problems with +Inf and loss of accuracy */
+            return pnchisq.evaluate(x * df1, df1, ncp, lowerTail, logP);
+        }
+
+        y = (df1 / df2) * x;
+        return pnbeta.pnbeta2(y / (1. + y), 1. / (1. + y), df1 / 2., df2 / 2.,
+                        ncp, lowerTail, logP);
+    }
+}
diff --git a/com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/stats/Pt.java b/com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/stats/Pt.java
new file mode 100644
index 0000000000000000000000000000000000000000..f1ef9bf8a51c42b38e04316414d2ced717bcf10a
--- /dev/null
+++ b/com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/stats/Pt.java
@@ -0,0 +1,83 @@
+/*
+ * This material is distributed under the GNU General Public License
+ * Version 2. You may review the terms of this license at
+ * http://www.gnu.org/licenses/gpl-2.0.html
+ *
+ * Copyright (c) 1995, 1996, Robert Gentleman and Ross Ihaka
+ * Copyright (c) 2000-2007, The R Core Team
+ * Copyright (c) 2016, Oracle and/or its affiliates
+ *
+ * All rights reserved.
+ */
+package com.oracle.truffle.r.library.stats;
+
+import static com.oracle.truffle.r.library.stats.LBeta.lbeta;
+import static com.oracle.truffle.r.library.stats.MathConstants.M_LN2;
+import static com.oracle.truffle.r.library.stats.Pbeta.pbeta;
+
+import com.oracle.truffle.api.profiles.BranchProfile;
+import com.oracle.truffle.r.library.stats.StatsFunctions.Function2_2;
+
+public final class Pt implements Function2_2 {
+    private final BranchProfile pbetaNanProfile = BranchProfile.create();
+    private final Pnorm pnorm = new Pnorm();
+
+    @Override
+    public double evaluate(double x, double n, boolean lowerTail, boolean logP) {
+        /*
+         * return P[ T <= x ] where T ~ t_{n} (t distrib. with n degrees of freedom).
+         *
+         * --> ./pnt.c for NON-central
+         */
+        if (Double.isNaN(x) || Double.isNaN(n)) {
+            return x + n;
+        }
+
+        if (n <= 0.0) {
+            return RMathError.defaultError();
+        }
+
+        if (!Double.isFinite(x)) {
+            return (x < 0) ? DPQ.rdt0(lowerTail, logP) : DPQ.rdt1(lowerTail, logP);
+        }
+        if (!Double.isFinite(n)) {
+            return pnorm.evaluate(x, 0.0, 1.0, lowerTail, logP);
+        }
+
+        double nx = 1 + (x / n) * x;
+        /*
+         * FIXME: This test is probably losing rather than gaining precision, now that pbeta(*,
+         * log_p = true) is much better. Note however that a version of this test *is* needed for
+         * x*x > D_MAX
+         */
+        double val;
+        if (nx > 1e100) { /* <==> x*x > 1e100 * n */
+            /*
+             * Danger of underflow. So use Abramowitz & Stegun 26.5.4 pbeta(z, a, b) ~ z^a(1-z)^b /
+             * aB(a,b) ~ z^a / aB(a,b), with z = 1/nx, a = n/2, b= 1/2 :
+             */
+            double lval;
+            lval = -0.5 * n * (2 * Math.log(Math.abs(x)) - Math.log(n)) - lbeta(0.5 * n, 0.5) - Math.log(0.5 * n);
+            val = logP ? lval : Math.exp(lval);
+        } else {
+            val = (n > x * x)
+                            ? pbeta(x * x / (n + x * x), 0.5, n / 2., /* lower_tail */false, logP, pbetaNanProfile)
+                            : pbeta(1. / nx, n / 2., 0.5, /* lower_tail */true, logP, pbetaNanProfile);
+        }
+
+        /* Use "1 - v" if lower_tail and x > 0 (but not both): */
+        boolean newLowerTail = x <= 0. ? !lowerTail : lowerTail;
+
+        if (logP) {
+            if (newLowerTail) {
+                return RMath.log1p(-0.5 * Math.exp(val));
+            } else {
+                return val - M_LN2; /* = Math.log(.5* pbeta(....)) */
+            }
+        } else {
+            val /= 2.;
+            return DPQ.rdcval(val, newLowerTail);
+        }
+
+    }
+}
diff --git a/com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/stats/QBeta.java b/com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/stats/QBeta.java
new file mode 100644
index 0000000000000000000000000000000000000000..8e8c7512edb90b564a5677756a68258f040b6c3a
--- /dev/null
+++ b/com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/stats/QBeta.java
@@ -0,0 +1,661 @@
+/*
+ * This material is distributed under the GNU General Public License
+ * Version 2. You may review the terms of this license at
+ * http://www.gnu.org/licenses/gpl-2.0.html
+ *
+ * Copyright (c) 1995, 1996, Robert Gentleman and Ross Ihaka
+ * Copyright (c) 1998-2015, The R Core Team
+ * Copyright (c) 2016, Oracle and/or its affiliates
+ *
+ * All rights reserved.
+ */
+/*
+ *  based on code (C) 1979 and later Royal Statistical Society
+ *
+ * Reference:
+ * Cran, G. W., K. J. Martin and G. E. Thomas (1977).
+ *      Remark AS R19 and Algorithm AS 109,
+ *      Applied Statistics, 26(1), 111-114.
+ * Remark AS R83 (v.39, 309-310) and the correction (v.40(1) p.236)
+ *      have been incorporated in this version.
+ */
+package com.oracle.truffle.r.library.stats;
+
+import static com.oracle.truffle.r.library.stats.Arithmetic.powDi;
+import static com.oracle.truffle.r.library.stats.LBeta.lbeta;
+import static com.oracle.truffle.r.library.stats.MathConstants.DBL_MANT_DIG;
+import static com.oracle.truffle.r.library.stats.MathConstants.DBL_MIN;
+import static com.oracle.truffle.r.library.stats.MathConstants.DBL_MIN_EXP;
+import static com.oracle.truffle.r.library.stats.MathConstants.ML_NAN;
+import static com.oracle.truffle.r.library.stats.MathConstants.M_LN2;
+import static com.oracle.truffle.r.library.stats.Pbeta.pbetaRaw;
+
+import com.oracle.truffle.api.CompilerDirectives.TruffleBoundary;
+import com.oracle.truffle.r.library.stats.RMathError.MLError;
+import com.oracle.truffle.r.library.stats.StatsFunctions.Function3_2;
+import com.oracle.truffle.r.runtime.RError.Message;
+
+public final class QBeta implements Function3_2 {
+    private static final double USE_LOG_X_CUTOFF = -5.;
+    private static final int N_NEWTON_FREE = 4;
+    // TODO: find out why this??? Is swap_01 R logical??
+    private static final int MLOGICAL_NA = -1;
+
+    @Override
+    public double evaluate(double alpha, double p, double q, boolean lowerTail, boolean logP) {
+        if (Double.isNaN(p) || Double.isNaN(q) || Double.isNaN(alpha)) {
+            return p + q + alpha;
+        }
+
+        if (p < 0. || q < 0.) {
+            return RMathError.defaultError();
+        }
+        // allowing p==0 and q==0 <==> treat as one- or two-point mass
+
+        double[] qbet = new double[2]; // = { qbeta(), 1 - qbeta() }
+        new QBetaRawMethod().qbeta_raw(alpha, p, q, lowerTail, logP, MLOGICAL_NA, USE_LOG_X_CUTOFF, N_NEWTON_FREE, qbet);
+        return qbet[0];
+
+    }
+
+    /**
+     * Debugging printfs should print exactly the same output as GnuR, this can help with debugging.
+     */
+    @SuppressWarnings("unused")
+    private static void debugPrintf(String fmt, Object... args) {
+        // System.out.printf(fmt + "\n", args);
+    }
+
+    private static final double acu_min = 1e-300;
+    private static final double log_eps_c = M_LN2 * (1. - DBL_MANT_DIG); // = log(DBL_EPSILON) =
+                                                                         // -36.04..;
+    private static final double fpu = 3e-308;
+    private static final double p_lo = fpu;
+    private static final double p_hi = 1 - 2.22e-16;
+
+    private static final double const1 = 2.30753;
+    private static final double const2 = 0.27061;
+    private static final double const3 = 0.99229;
+    private static final double const4 = 0.04481;
+
+    private static final double DBL_very_MIN = DBL_MIN / 4.;
+    private static final double DBL_log_v_MIN = M_LN2 * (DBL_MIN_EXP - 2);
+    private static final double DBL_1__eps = 0x1.fffffffffffffp-1; // = 1 - 2^-53
+
+    // The fields and variables are named after local variables from GnuR, we keep the original
+    // names for the ease of debugging
+    // Checkstyle: stop field name check
+    private static final class QBetaRawMethod {
+        private boolean give_log_q;
+        private boolean use_log_x;
+        private boolean add_N_step;
+        private double logbeta;
+        private boolean swap_tail;
+        private double a;
+        private double la;
+        private double pp;
+        private double qq;
+        private double r;
+        private double t;
+        private double tx;
+        private double u_n;
+        private double xinbta;
+        private double u;
+        private boolean warned;
+        private double acu;
+        private double y;
+        private double w;
+        private boolean log_; // or u < log_q_cut below
+        private double p_;
+        private double u0;
+        private double s;
+        private double h;
+        boolean bad_u;
+        boolean bad_init;
+        private double g;
+        private double D;
+
+        /**
+         *
+         * @param alpha
+         * @param p
+         * @param q
+         * @param lower_tail
+         * @param log_p
+         * @param swap_01 {true, NA, false}: if NA, algorithm decides swap_tail
+         * @param log_q_cut if == Inf: return Math.log(qbeta(..)); otherwise, if finite: the bound
+         *            for switching to Math.log(x)-scale; see use_log_x
+         * @param n_N number of "unconstrained" Newton steps before switching to constrained
+         * @param qb The result will be saved to this 2 dimensional array = qb[0:1] = { qbeta(), 1 -
+         *            qbeta() }.
+         */
+        @TruffleBoundary
+        private void qbeta_raw(double alpha, double p, double q, boolean lower_tail, boolean log_p,
+                        int swap_01,
+                        double log_q_cut,
+                        int n_N,
+                        double[] qb) {
+            give_log_q = (log_q_cut == Double.POSITIVE_INFINITY);
+            use_log_x = give_log_q;
+            add_N_step = true;
+            y = -1.;
+
+            // Assuming p >= 0, q >= 0 here ...
+
+            // Deal with boundary cases here:
+            if (alpha == DPQ.rdt0(lower_tail, log_p)) {
+                returnQ0(qb, give_log_q);
+                return;
+            }
+            if (alpha == DPQ.rdt1(lower_tail, log_p)) {
+                returnQ1(qb, give_log_q);
+                return;
+            }
+
+            // check alpha {*before* transformation which may all accuracy}:
+            if ((log_p && alpha > 0) ||
+                            (!log_p && (alpha < 0 || alpha > 1))) { // alpha is outside
+                debugPrintf("qbeta(alpha=%g, %g, %g, .., log_p=%d): %s%s\n",
+                                alpha, p, q, log_p, "alpha not in ",
+                                log_p ? "[-Inf, 0]" : "[0,1]");
+                // ML_ERR_return_NAN :
+                RMathError.error(MLError.DOMAIN, "");
+                qb[0] = qb[1] = ML_NAN;
+                return;
+            }
+
+            // p==0, q==0, p = Inf, q = Inf <==> treat as one- or two-point mass
+            if (p == 0 || q == 0 || !Double.isFinite(p) || !Double.isFinite(q)) {
+                // We know 0 < T(alpha) < 1 : pbeta() is constant and trivial in {0, 1/2, 1}
+                debugPrintf(
+                                "qbeta(%g, %g, %g, lower_t=%d, log_p=%d): (p,q)-boundary: trivial\n",
+                                alpha, p, q, lower_tail, log_p);
+                if (p == 0 && q == 0) { // point mass 1/2 at each of {0,1} :
+                    if (alpha < DPQ.rdhalf(log_p)) {
+                        returnQ0(qb, give_log_q);
+                    } else if (alpha > DPQ.rdhalf(log_p)) {
+                        returnQ1(qb, give_log_q);
+                    } else {
+                        returnQHalf(qb, give_log_q);
+                    }
+                    return;
+                } else if (p == 0 || p / q == 0) { // point mass 1 at 0 - "flipped around"
+                    returnQ0(qb, give_log_q);
+                } else if (q == 0 || q / p == 0) { // point mass 1 at 0 - "flipped around"
+                    returnQ1(qb, give_log_q);
+                } else {
+                    // else: p = q = Inf : point mass 1 at 1/2
+                    returnQHalf(qb, give_log_q);
+                }
+                return;
+            }
+
+            p_ = DPQ.rdtqiv(alpha, lower_tail, log_p);
+            logbeta = lbeta(p, q);
+            boolean swap_choose = (swap_01 == MLOGICAL_NA);
+            swap_tail = swap_choose ? (p_ > 0.5) : swap_01 != 0;
+            if (swap_tail) { /* change tail, swap p <-> q : */
+                a = DPQ.rdtciv(alpha, lower_tail, log_p); // = 1 - p_ < 1/2
+                /* la := log(a), but without numerical cancellation: */
+                la = DPQ.rdtclog(alpha, lower_tail, log_p);
+                pp = q;
+                qq = p;
+            } else {
+                a = p_;
+                la = DPQ.rdtlog(alpha, lower_tail, log_p);
+                pp = p;
+                qq = q;
+            }
+
+            /* calculate the initial approximation */
+
+            /*
+             * Desired accuracy for Newton iterations (below) should depend on (a,p) This is from
+             * Remark .. on AS 109, adapted. However, it's not clear if this is "optimal" for IEEE
+             * double prec.
+             *
+             * acu = fmax2(acu_min, pow(10., -25. - 5./(pp * pp) - 1./(a * a)));
+             *
+             * NEW: 'acu' accuracy NOT for squared adjustment, but simple; ---- i.e., "new acu" =
+             * sqrt(old acu)
+             */
+            acu = Math.max(acu_min, Math.pow(10., -13. - 2.5 / (pp * pp) - 0.5 / (a * a)));
+            // try to catch "extreme left tail" early
+            u0 = (la + Math.log(pp) + logbeta) / pp; // = log(x_0)
+            r = pp * (1. - qq) / (pp + 1.);
+            t = 0.2;
+
+            debugPrintf(
+                            "qbeta(%g, %g, %g, lower_t=%b, log_p=%b):%s\n" +
+                                            "  swap_tail=%b, la=%g, u0=%g (bnd: %g (%g)) ",
+                            alpha, p, q, lower_tail, log_p,
+                            (log_p && (p_ == 0. || p_ == 1.)) ? (p_ == 0. ? " p_=0" : " p_=1") : "",
+                            swap_tail, la, u0,
+                            (t * log_eps_c - Math.log(Math.abs(pp * (1. - qq) * (2. - qq) / (2. * (pp + 2.))))) / 2.,
+                            t * log_eps_c - Math.log(Math.abs(r)));
+
+            tx = 0.;
+            if (M_LN2 * DBL_MIN_EXP < u0 && // cannot allow exp(u0) = 0 ==> exp(u1) = exp(u0) = 0
+                            u0 < -0.01 && // (must: u0 < 0, but too close to 0 <==> x = exp(u0) =
+                            // 0.99..)
+                            // qq <= 2 && // <--- "arbitrary"
+                            // u0 < t*log_eps_c - log(fabs(r)) &&
+                            u0 < (t * log_eps_c - Math.log(Math.abs(pp * (1. - qq) * (2. - qq) / (2. * (pp + 2.))))) / 2.) {
+                // TODO: maybe jump here from below, when initial u "fails" ?
+                // L_tail_u:
+                // MM's one-step correction (cheaper than 1 Newton!)
+                r = r * Math.exp(u0); // = r*x0
+                if (r > -1.) {
+                    u = u0 - RMath.log1p(r) / pp;
+                    debugPrintf("u1-u0=%9.3g --> choosing u = u1\n", u - u0);
+                } else {
+                    u = u0;
+                    debugPrintf("cannot cheaply improve u0\n");
+                }
+                tx = xinbta = Math.exp(u);
+                use_log_x = true; // or (u < log_q_cut) ??
+                newton(n_N, log_p, qb);
+                return;
+            }
+
+            // y := y_\alpha in AS 64 := Hastings(1955) approximation of qnorm(1 - a) :
+            r = Math.sqrt(-2 * la);
+            y = r - (const1 + const2 * r) / (1. + (const3 + const4 * r) * r);
+
+            if (pp > 1 && qq > 1) { // use Carter(1947), see AS 109, remark '5.'
+                r = (y * y - 3.) / 6.;
+                s = 1. / (pp + pp - 1.);
+                t = 1. / (qq + qq - 1.);
+                h = 2. / (s + t);
+                w = y * Math.sqrt(h + r) / h - (t - s) * (r + 5. / 6. - 2. / (3. * h));
+                debugPrintf("p,q > 1 => w=%g", w);
+                if (w > 300) { // Math.exp(w+w) is huge or overflows
+                    t = w + w + Math.log(qq) - Math.log(pp); // = argument of log1pMath.exp(.)
+                    u = // Math.log(xinbta) = - log1p(qq/pp * Math.exp(w+w)) = -Math.log(1 +
+                        // Math.exp(t))
+                                    (t <= 18) ? -RMath.log1p(Math.exp(t)) : -t - Math.exp(-t);
+                    xinbta = Math.exp(u);
+                } else {
+                    xinbta = pp / (pp + qq * Math.exp(w + w));
+                    u = // Math.log(xinbta)
+                                    -RMath.log1p(qq / pp * Math.exp(w + w));
+                }
+            } else { // use the original AS 64 proposal, Scheffé-Tukey (1944) and Wilson-Hilferty
+                r = qq + qq;
+                /*
+                 * A slightly more stable version of t := \chi^2_{alpha} of AS 64 t = 1. / (9. *
+                 * qq); t = r * R_pow_di(1. - t + y * Math.sqrt(t), 3);
+                 */
+                t = 1. / (3. * Math.sqrt(qq));
+                t = r * powDi(1. + t * (-t + y), 3); // = \chi^2_{alpha} of AS 64
+                s = 4. * pp + r - 2.; // 4p + 2q - 2 = numerator of new t = (...) / chi^2
+                debugPrintf("min(p,q) <= 1: t=%g", t);
+                if (t == 0 || (t < 0. && s >= t)) { // cannot use chisq approx
+                    // x0 = 1 - { (1-a)*q*B(p,q) } ^{1/q} {AS 65}
+                    // xinbta = 1. - Math.exp((Math.log(1-a)+ Math.log(qq) + logbeta) / qq);
+                    double l1ma; /*
+                                  * := Math.log(1-a), directly from alpha (as 'la' above): FIXME:
+                                  * not worth it? log1p(-a) always the same ??
+                                  */
+                    if (swap_tail) {
+                        l1ma = DPQ.rdtlog(alpha, lower_tail, log_p);
+                    } else {
+                        l1ma = DPQ.rdtclog(alpha, lower_tail, log_p);
+                    }
+                    debugPrintf(" t <= 0 : log1p(-a)=%.15g, better l1ma=%.15g\n", RMath.log1p(-a), l1ma);
+                    double xx = (l1ma + Math.log(qq) + logbeta) / qq;
+                    if (xx <= 0.) {
+                        xinbta = -RMath.expm1(xx);
+                        u = DPQ.rlog1exp(xx); // = Math.log(xinbta) = Math.log(1 -
+                                              // Math.exp(...A...))
+                    } else { // xx > 0 ==> 1 - e^xx < 0 .. is nonsense
+                        debugPrintf(" xx=%g > 0: xinbta:= 1-e^xx < 0\n", xx);
+                        xinbta = 0;
+                        u = Double.NEGATIVE_INFINITY; /// FIXME can do better?
+                    }
+                } else {
+                    t = s / t;
+                    debugPrintf(" t > 0 or s < t < 0:  new t = %g ( > 1 ?)\n", t);
+                    if (t <= 1.) { // cannot use chisq, either
+                        u = (la + Math.log(pp) + logbeta) / pp;
+                        xinbta = Math.exp(u);
+                    } else { // (1+x0)/(1-x0) = t, solved for x0 :
+                        xinbta = 1. - 2. / (t + 1.);
+                        u = RMath.log1p(-2. / (t + 1.));
+                    }
+                }
+            }
+
+            // Problem: If initial u is completely wrong, we make a wrong decision here
+            if (swap_choose &&
+                            ((swap_tail && u >= -Math.exp(log_q_cut)) || // ==> "swap back"
+                                            (!swap_tail && u >= -Math.exp(4 * log_q_cut) && pp / qq < 1000.))) { // ==>
+                // "swap
+                // now"
+                // (much
+                // less
+                // easily)
+                // "revert swap" -- and use_log_x
+                swap_tail = !swap_tail;
+                debugPrintf(" u = %g (e^u = xinbta = %.16g) ==> ", u, xinbta);
+                if (swap_tail) {
+                    a = DPQ.rdtciv(alpha, lower_tail, log_p); // needed ?
+                    la = DPQ.rdtclog(alpha, lower_tail, log_p);
+                    pp = q;
+                    qq = p;
+                } else {
+                    a = p_;
+                    la = DPQ.rdtlog(alpha, lower_tail, log_p);
+                    pp = p;
+                    qq = q;
+                }
+                debugPrintf("\"%s\"; la = %g\n",
+                                (swap_tail ? "swap now" : "swap back"), la);
+                // we could redo computations above, but this should be stable
+                u = DPQ.rlog1exp(u);
+                xinbta = Math.exp(u);
+
+                /*
+                 * Careful: "swap now" should not fail if 1) the above initial xinbta is
+                 * "completely wrong" 2) The correction step can go outside (u_n > 0 ==> e^u > 1 is
+                 * illegal) e.g., for qbeta(0.2066, 0.143891, 0.05)
+                 */
+            }
+
+            if (!use_log_x) {
+                use_log_x = (u < log_q_cut); // (per default) <==> xinbta = e^u < 4.54e-5
+            }
+            bad_u = !Double.isFinite(u);
+            bad_init = bad_u || xinbta > p_hi;
+
+            debugPrintf(" -> u = %g, e^u = xinbta = %.16g, (Newton acu=%g%s)\n",
+                            u, xinbta, acu,
+                            (bad_u ? ", ** bad u **" : (use_log_x ? ", on u = Math.log(x) scale" : "")));
+
+            u_n = 1.;
+            tx = xinbta; // keeping "original initial x" (for now)
+
+            if (bad_u || u < log_q_cut) { /*
+                                           * e.g. qbeta(0.21, .001, 0.05) try "left border" quickly,
+                                           * i.e., try at smallest positive number:
+                                           */
+                w = pbetaRaw(DBL_very_MIN, pp, qq, true, log_p);
+                if (w > (log_p ? la : a)) {
+                    debugPrintf(" quantile is left of smallest positive number; \"convergence\"\n");
+                    if (log_p || Math.abs(w - a) < Math.abs(0 - a)) { // DBL_very_MIN is better than
+                                                                      // 0
+                        tx = DBL_very_MIN;
+                        u_n = DBL_log_v_MIN; // = Math.log(DBL_very_MIN)
+                    } else {
+                        tx = 0.;
+                        u_n = Double.NEGATIVE_INFINITY;
+                    }
+                    use_log_x = log_p;
+                    add_N_step = false;
+                    finalStep(log_p, qb);
+                    return;
+                } else {
+                    debugPrintf(" pbeta(smallest pos.) = %g <= %g  --> continuing\n",
+                                    w, (log_p ? la : a));
+                    if (u < DBL_log_v_MIN) {
+                        u = DBL_log_v_MIN; // = Math.log(DBL_very_MIN)
+                        xinbta = DBL_very_MIN;
+                    }
+                }
+            }
+
+            /* Sometimes the approximation is negative (and == 0 is also not "ok") */
+            if (bad_init && !(use_log_x && tx > 0)) {
+                if (u == Double.NEGATIVE_INFINITY) {
+                    debugPrintf("  u = -Inf;");
+                    u = M_LN2 * DBL_MIN_EXP;
+                    xinbta = DBL_MIN;
+                } else {
+                    debugPrintf(" bad_init: u=%g, xinbta=%g;", u, xinbta);
+                    xinbta = (xinbta > 1.1) // i.e. "way off"
+                                    ? 0.5 // otherwise, keep the respective boundary:
+                                    : ((xinbta < p_lo) ? Math.exp(u) : p_hi);
+                    if (bad_u) {
+                        u = Math.log(xinbta);
+                    }
+                    // otherwise: not changing "potentially better" u than the above
+                }
+                debugPrintf(" -> (partly)new u=%g, xinbta=%g\n", u, xinbta);
+            }
+
+            newton(n_N, log_p, qb);
+            // note: newton calls converged which calls finalStep
+        }
+
+        private void newton(int n_N, boolean log_p, double[] qb) {
+            /*
+             * --------------------------------------------------------------------
+             *
+             * Solve for x by a modified Newton-Raphson method, using pbeta_raw()
+             */
+            r = 1 - pp;
+            t = 1 - qq;
+            double wprev = 0.;
+            double prev = 1.;
+            double adj = 1.;
+
+            if (use_log_x) { // find Math.log(xinbta) -- work in u := Math.log(x) scale
+                // if (bad_init && tx > 0) { xinbta = tx; }// may have been better
+                for (int i_pb = 0; i_pb < 1000; i_pb++) {
+                    // using log_p == true unconditionally here
+                    // FIXME: if Math.exp(u) = xinbta underflows to 0, like different formula
+                    // pbeta_Math.log(u, *)
+                    y = pbetaRaw(xinbta, pp, qq, /* lower_tail = */ true, true);
+
+                    /*
+                     * w := Newton step size for L(u) = log F(e^u) =!= 0; u := Math.log(x) = (L(.) -
+                     * la) / L'(.); L'(u)= (F'(e^u) * e^u ) / F(e^u) = (L(.) - la)*F(.) / {F'(e^u) *
+                     * e^u } = = (L(.) - la) * e^L(.) * e^{-log F'(e^u) - u} = ( y - la) * e^{ y - u
+                     * -log F'(e^u)} and -log F'(x)= -log f(x) = + logbeta + (1-p) Math.log(x) +
+                     * (1-q) Math.log(1-x) = logbeta + (1-p) u + (1-q) Math.log(1-e^u)
+                     */
+                    w = (y == Double.NEGATIVE_INFINITY) // y = -Inf well possible: we are on
+                                                        // log scale!
+                                    ? 0. : (y - la) * Math.exp(y - u + logbeta + r * u + t * DPQ.rlog1exp(u));
+                    if (!Double.isFinite(w)) {
+                        break;
+                    }
+                    if (i_pb >= n_N && w * wprev <= 0.) {
+                        prev = RMath.fmax2(Math.abs(adj), fpu);
+                    }
+                    debugPrintf("N(i=%2d): u=%g, pb(e^u)=%g, w=%g, %s prev=%g,",
+                                    i_pb, u, y, w, (w * wprev <= 0.) ? "new" : "old", prev);
+                    g = 1;
+                    int i_inn;
+                    for (i_inn = 0; i_inn < 1000; i_inn++) {
+                        adj = g * w;
+                        // take full Newton steps at the beginning; only then safe guard:
+                        if (i_pb < n_N || Math.abs(adj) < prev) {
+                            u_n = u - adj; // u_{n+1} = u_n - g*w
+                            if (u_n <= 0.) { // <==> 0 < xinbta := e^u <= 1
+                                if (prev <= acu || Math.abs(w) <= acu) {
+                                    /* R_ifDEBUG_printf(" -adj=%g, %s <= acu  ==> convergence\n", */
+                                    /* -adj, (prev <= acu) ? "prev" : "|w|"); */
+                                    debugPrintf(" it{in}=%d, -adj=%g, %s <= acu  ==> convergence\n",
+                                                    i_inn, -adj, (prev <= acu) ? "prev" : "|w|");
+                                    converged(log_p, qb);
+                                    return;
+                                }
+                                // if (u_n != Double.NEGATIVE_INFINITY && u_n != 1)
+                                break;
+                            }
+                        }
+                        g /= 3;
+                    }
+                    // (cancellation in (u_n -u) => may differ from adj:
+                    D = RMath.fmin2(Math.abs(adj), Math.abs(u_n - u));
+                    /* R_ifDEBUG_printf(" delta(u)=%g\n", u_n - u); */
+                    debugPrintf(" it{in}=%d, delta(u)=%9.3g, D/|.|=%.3g\n",
+                                    i_inn, u_n - u, D / Math.abs(u_n + u));
+                    if (D <= 4e-16 * Math.abs(u_n + u)) {
+                        converged(log_p, qb);
+                        return;
+                    }
+                    u = u_n;
+                    xinbta = Math.exp(u);
+                    wprev = w;
+                } // for(i )
+
+            } else {
+                for (int i_pb = 0; i_pb < 1000; i_pb++) {
+                    y = pbetaRaw(xinbta, pp, qq, /* lower_tail = */ true, log_p);
+                    // delta{y} : d_y = y - (log_p ? la : a);
+
+                    if (!Double.isFinite(y) && !(log_p && y == Double.NEGATIVE_INFINITY)) { // y =
+                                                                                            // -Inf
+                        // is ok if
+                        // (log_p)
+                        RMathError.error(MLError.DOMAIN, "");
+                        qb[0] = qb[1] = ML_NAN;
+                        return;
+                    }
+
+                    /*
+                     * w := Newton step size (F(.) - a) / F'(.) or, -- log: (lF - la) / (F' / F) =
+                     * Math.exp(lF) * (lF - la) / F'
+                     */
+                    w = log_p
+                                    ? (y - la) * Math.exp(y + logbeta + r * Math.log(xinbta) + t * Math.log1p(-xinbta))
+                                    : (y - a) * Math.exp(logbeta + r * Math.log(xinbta) + t * Math.log1p(-xinbta));
+                    if (i_pb >= n_N && w * wprev <= 0.)
+                        prev = RMath.fmax2(Math.abs(adj), fpu);
+                    debugPrintf("N(i=%2d): x0=%#17.15g, pb(x0)=%#17.15g, w=%#17.15g, %s prev=%g,",
+                                    i_pb, xinbta, y, w, (w * wprev <= 0.) ? "new" : "old", prev);
+                    g = 1;
+                    int i_inn;
+                    for (i_inn = 0; i_inn < 1000; i_inn++) {
+                        adj = g * w;
+                        // take full Newton steps at the beginning; only then safe guard:
+                        if (i_pb < n_N || Math.abs(adj) < prev) {
+                            tx = xinbta - adj; // x_{n+1} = x_n - g*w
+                            if (0. <= tx && tx <= 1.) {
+                                if (prev <= acu || Math.abs(w) <= acu) {
+                                    debugPrintf(" it{in}=%d, delta(x)=%g, %s <= acu  ==> convergence\n",
+                                                    i_inn, -adj, (prev <= acu) ? "prev" : "|w|");
+                                    converged(log_p, qb);
+                                    return;
+                                }
+                                if (tx != 0. && tx != 1) {
+                                    break;
+                                }
+                            }
+                        }
+                        g /= 3;
+                    }
+                    debugPrintf(" it{in}=%d, delta(x)=%g\n", i_inn, tx - xinbta);
+                    if (Math.abs(tx - xinbta) <= 4e-16 * (tx + xinbta)) { // "<=" : (.) == 0
+                        converged(log_p, qb);
+                        return;
+                    }
+                    xinbta = tx;
+                    if (tx == 0) { // "we have lost"
+                        break;
+                    }
+                    wprev = w;
+                }
+            }
+
+            /*-- NOT converged: Iteration count --*/
+            warned = true;
+            RMathError.error(MLError.PRECISION, "qbeta");
+
+            converged(log_p, qb);
+        }
+
+        private void converged(boolean log_p, double[] qb) {
+            log_ = log_p || use_log_x; // only for printing
+            debugPrintf(" %s: Final delta(y) = %g%s\n",
+                            warned ? "_NO_ convergence" : "converged",
+                            y - (log_ ? la : a), (log_ ? " (log_)" : ""));
+            if ((log_ && y == Double.NEGATIVE_INFINITY) || (!log_ && y == 0)) {
+                // stuck at left, try if smallest positive number is "better"
+                w = pbetaRaw(DBL_very_MIN, pp, qq, true, log_);
+                if (log_ || Math.abs(w - a) <= Math.abs(y - a)) {
+                    tx = DBL_very_MIN;
+                    u_n = DBL_log_v_MIN; // = Math.log(DBL_very_MIN)
+                }
+                add_N_step = false; // not trying to do better anymore
+            } else if (!warned && (log_ ? Math.abs(y - la) > 3 : Math.abs(y - a) > 1e-4)) {
+                if (!(log_ && y == Double.NEGATIVE_INFINITY &&
+                                // e.g. qbeta(-1e-10, .2, .03, log=true) cannot get accurate ==> do
+                                // NOT
+                                // warn
+                                pbetaRaw(DBL_1__eps, // = 1 - eps
+                                                pp, qq, true, true) > la + 2)) {
+                    RMathError.warning(Message.QBETA_ACURACY_WARNING, (log_ ? ", log_" : ""), Math.abs(y - (log_ ? la : a)));
+                }
+            }
+
+            finalStep(log_p, qb);
+        }
+
+        /**
+         * Represents a block of code that is labelled "L_return" in the original source, should be
+         * followed by a return.
+         */
+        private void finalStep(boolean log_p, double[] qb) {
+            if (give_log_q) { // ==> use_log_x , too
+                if (!use_log_x) { // (see if claim above is true)
+                    RMathError.warning(Message.GENERIC,
+                                    "qbeta() L_return, u_n=%g;  give_log_q=true but use_log_x=false -- please report!",
+                                    u_n);
+                }
+
+                double rr = DPQ.rlog1exp(u_n);
+                swapTail(qb, swap_tail, u_n, rr);
+            } else {
+                if (use_log_x) {
+                    if (add_N_step) {
+                        /*
+                         * add one last Newton step on original x scale, e.g., for qbeta(2^-98,
+                         * 0.125, 2^-96)
+                         */
+                        double tmpXinbta = Math.exp(u_n);
+                        y = pbetaRaw(tmpXinbta, pp, qq, /* lower_tail = */ true, log_p);
+                        w = log_p
+                                        ? (y - la) * Math.exp(y + logbeta + r * Math.log(tmpXinbta) + t * RMath.log1p(-tmpXinbta))
+                                        : (y - a) * Math.exp(logbeta + r * Math.log(tmpXinbta) + t * RMath.log1p(-tmpXinbta));
+                        tx = tmpXinbta - w;
+                        debugPrintf(
+                                        "Final Newton correction(non-log scale): xinbta=%.16g, y=%g, w=%g. => new tx=%.16g\n",
+                                        tmpXinbta, y, w, tx);
+                    } else {
+                        swapTail(qb, swap_tail, Math.exp(u_n), -RMath.expm1(u_n));
+                        return;
+                    }
+                }
+                swapTail(qb, swap_tail, tx, 1 - tx);
+            }
+        }
+
+        private static void swapTail(double[] qb, boolean swap_tail, double val0, double val1) {
+            if (swap_tail) {
+                qb[0] = val1;
+                qb[1] = val0;
+            } else {
+                qb[0] = val0;
+                qb[1] = val1;
+            }
+        }
+
+        private static void returnQ0(double[] qb, boolean give_log_q) {
+            qb[0] = DPQ.rd0(give_log_q);
+            qb[1] = DPQ.rd1(give_log_q);
+        }
+
+        private static void returnQ1(double[] qb, boolean give_log_q) {
+            qb[0] = DPQ.rd1(give_log_q);
+            qb[1] = DPQ.rd0(give_log_q);
+        }
+
+        private static void returnQHalf(double[] qb, boolean give_log_q) {
+            qb[0] = DPQ.rdhalf(give_log_q);
+            qb[1] = DPQ.rdhalf(give_log_q);
+        }
+    }
+}
diff --git a/com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/stats/QHyper.java b/com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/stats/QHyper.java
index c3a43d3259eba623afcabfc64774ea901a893bbf..727442b4a6e71be54ee08d0e1b37691163aa4d0a 100644
--- a/com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/stats/QHyper.java
+++ b/com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/stats/QHyper.java
@@ -12,37 +12,35 @@
 package com.oracle.truffle.r.library.stats;
 
 import static com.oracle.truffle.r.library.stats.MathConstants.DBL_EPSILON;
-import static com.oracle.truffle.r.library.stats.MathConstants.forceint;
 import static com.oracle.truffle.r.library.stats.RMath.fmax2;
 import static com.oracle.truffle.r.library.stats.RMath.fmin2;
+import static com.oracle.truffle.r.library.stats.RMath.forceint;
 import static com.oracle.truffle.r.library.stats.RMath.lfastchoose;
 
 import com.oracle.truffle.r.library.stats.DPQ.EarlyReturn;
+import com.oracle.truffle.r.library.stats.StatsFunctions.Function4_2;
 
-public final class QHyper {
-    public static double qhyper(double p, double nr, double nb, double n, boolean lowerTail, boolean logP) {
+public final class QHyper implements Function4_2 {
+    @Override
+    public double evaluate(double p, double nr, double nb, double n, boolean lowerTail, boolean logP) {
+        return qhyper(p, nr, nb, n, lowerTail, logP);
+    }
+
+    public static double qhyper(double pIn, double nrIn, double nbIn, double nIn, boolean lowerTail, boolean logP) {
         /* This is basically the same code as ./phyper.c *used* to be --> FIXME! */
-        double capN;
-        double xstart;
-        double xend;
-        double xr;
-        double xb;
-        double sum;
-        double term;
-        boolean smallN;
-        if (Double.isNaN(p) || Double.isNaN(nr) || Double.isNaN(nb) || Double.isNaN(n)) {
-            return p + nr + nb + n;
+        if (Double.isNaN(pIn) || Double.isNaN(nrIn) || Double.isNaN(nbIn) || Double.isNaN(nIn)) {
+            return pIn + nrIn + nbIn + nIn;
         }
-        if (!Double.isFinite(p) || !Double.isFinite(nr) || !Double.isFinite(nb) || !Double.isFinite(n)) {
-            return RMath.mlError();
+        if (!Double.isFinite(pIn) || !Double.isFinite(nrIn) || !Double.isFinite(nbIn) || !Double.isFinite(nIn)) {
+            return RMathError.defaultError();
         }
 
-        nr = forceint(nr);
-        nb = forceint(nb);
-        capN = nr + nb;
-        n = forceint(n);
+        double nr = forceint(nrIn);
+        double nb = forceint(nbIn);
+        double capN = nr + nb;
+        double n = forceint(nIn);
         if (nr < 0 || nb < 0 || n < 0 || n > capN) {
-            return RMath.mlError();
+            return RMathError.defaultError();
         }
 
         /*
@@ -50,24 +48,25 @@ public final class QHyper {
          * - 1, NR,NB, n)
          */
 
-        xstart = fmax2(0, n - nb);
-        xend = fmin2(n, nr);
+        double xstart = fmax2(0, n - nb);
+        double xend = fmin2(n, nr);
 
+        double p = pIn;
         try {
             DPQ.rqp01boundaries(p, xstart, xend, lowerTail, logP);
         } catch (EarlyReturn ex) {
             return ex.result;
         }
 
-        xr = xstart;
-        xb = n - xr; /* always ( = #{black balls in sample} ) */
+        double xr = xstart;
+        double xb = n - xr; /* always ( = #{black balls in sample} ) */
 
-        smallN = (capN < 1000); /* won't have underflow in product below */
+        boolean smallN = (capN < 1000); /* won't have underflow in product below */
         /*
          * if N is small, term := product.ratio( bin.coef ); otherwise work with its Math.logarithm
          * to protect against underflow
          */
-        term = lfastchoose(nr, xr) + lfastchoose(nb, xb) - lfastchoose(capN, n);
+        double term = lfastchoose(nr, xr) + lfastchoose(nb, xb) - lfastchoose(capN, n);
         if (smallN) {
             term = Math.exp(term);
         }
@@ -78,7 +77,7 @@ public final class QHyper {
             p = DPQ.rdtqiv(p, lowerTail, logP);
         }
         p *= 1 - 1000 * DBL_EPSILON; /* was 64, but failed on FreeBSD sometimes */
-        sum = smallN ? term : Math.exp(term);
+        double sum = smallN ? term : Math.exp(term);
 
         while (sum < p && xr < xend) {
             xr++;
@@ -94,5 +93,4 @@ public final class QHyper {
         }
         return xr;
     }
-
 }
diff --git a/com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/stats/QNBeta.java b/com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/stats/QNBeta.java
new file mode 100644
index 0000000000000000000000000000000000000000..ccbd2f19b13549768e8656333228e3b19e8c22bd
--- /dev/null
+++ b/com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/stats/QNBeta.java
@@ -0,0 +1,76 @@
+/*
+ * This material is distributed under the GNU General Public License
+ * Version 2. You may review the terms of this license at
+ * http://www.gnu.org/licenses/gpl-2.0.html
+ *
+ * Copyright (c) 2006, The R Core Team
+ * Copyright (c) 2016, Oracle and/or its affiliates
+ *
+ * All rights reserved.
+ */
+package com.oracle.truffle.r.library.stats;
+
+import static com.oracle.truffle.r.library.stats.MathConstants.DBL_EPSILON;
+import static com.oracle.truffle.r.library.stats.MathConstants.DBL_MIN;
+
+import com.oracle.truffle.r.library.stats.DPQ.EarlyReturn;
+import com.oracle.truffle.r.library.stats.StatsFunctions.Function4_2;
+
+public final class QNBeta implements Function4_2 {
+    private static final double accu = 1e-15;
+    private static final double Eps = 1e-14; /* must be > accu */
+
+    private final PNBeta pnbeta = new PNBeta();
+
+    @Override
+    public double evaluate(double pIn, double a, double b, double ncp, boolean lowerTail, boolean logP) {
+        if (Double.isNaN(pIn) || Double.isNaN(a) || Double.isNaN(b) || Double.isNaN(ncp)) {
+            return pIn + a + b + ncp;
+        }
+        if (!Double.isFinite(a)) {
+            return RMathError.defaultError();
+        }
+
+        if (ncp < 0. || a <= 0. || b <= 0.) {
+            return RMathError.defaultError();
+        }
+
+        try {
+            DPQ.rqp01boundaries(pIn, 0, 1, lowerTail, logP);
+        } catch (EarlyReturn e) {
+            return e.result;
+        }
+
+        double p = DPQ.rdtqiv(pIn, lowerTail, logP);
+
+        /*
+         * Invert pnbeta(.) : 1. finding an upper and lower bound
+         */
+        if (p > 1 - DBL_EPSILON) {
+            return 1.0;
+        }
+        double pp = RMath.fmin2(1 - DBL_EPSILON, p * (1 + Eps));
+        double ux = 0.5;
+        while (ux < 1 - DBL_EPSILON && pnbeta.evaluate(ux, a, b, ncp, true, false) < pp) {
+            ux = 0.5 * (1 + ux);
+        }
+        pp = p * (1 - Eps);
+        double lx = 0.5;
+        while (lx > DBL_MIN && pnbeta.evaluate(lx, a, b, ncp, true, false) > pp) {
+            lx *= 0.5;
+        }
+
+        /* 2. interval (lx,ux) halving : */
+        double nx;
+        do {
+            nx = 0.5 * (lx + ux);
+            if (pnbeta.evaluate(nx, a, b, ncp, true, false) > p) {
+                ux = nx;
+            } else {
+                lx = nx;
+            }
+        } while ((ux - lx) / nx > accu);
+
+        return 0.5 * (ux + lx);
+    }
+}
diff --git a/com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/stats/QNChisq.java b/com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/stats/QNChisq.java
new file mode 100644
index 0000000000000000000000000000000000000000..6673c76ce1cae3cb9c37a56ed8c5bc2e16d7b8f4
--- /dev/null
+++ b/com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/stats/QNChisq.java
@@ -0,0 +1,118 @@
+/*
+ * This material is distributed under the GNU General Public License
+ * Version 2. You may review the terms of this license at
+ * http://www.gnu.org/licenses/gpl-2.0.html
+ *
+ * Copyright (c) 1995, 1996  Robert Gentleman and Ross Ihaka
+ * Copyright (c) 2000-2008, The R Core Team
+ * Copyright (c) 2004, The R Foundation
+ * Copyright (c) 2016, Oracle and/or its affiliates
+ *
+ * All rights reserved.
+ */
+package com.oracle.truffle.r.library.stats;
+
+import static com.oracle.truffle.r.library.stats.MathConstants.DBL_EPSILON;
+import static com.oracle.truffle.r.library.stats.MathConstants.DBL_MAX;
+import static com.oracle.truffle.r.library.stats.MathConstants.DBL_MIN;
+
+import com.oracle.truffle.r.library.stats.Chisq.QChisq;
+import com.oracle.truffle.r.library.stats.DPQ.EarlyReturn;
+import com.oracle.truffle.r.library.stats.RMathError.MLError;
+import com.oracle.truffle.r.library.stats.StatsFunctions.Function3_2;
+
+public final class QNChisq implements Function3_2 {
+    private static final double accu = 1e-13;
+    private static final double racc = 4 * DBL_EPSILON;
+    /* these two are for the "search" loops, can have less accuracy: */
+    private static final double Eps = 1e-11; /* must be > accu */
+    private static final double rEps = 1e-10; /* relative tolerance ... */
+
+    private final QChisq qchisq = new QChisq();
+    private final PNChisq pnchisq = new PNChisq();
+
+    @Override
+    public double evaluate(double pIn, double df, double ncp, boolean lowerTail, boolean logP) {
+        if (Double.isNaN(pIn) || Double.isNaN(df) || Double.isNaN(ncp)) {
+            return pIn + df + ncp;
+        }
+        if (!Double.isFinite(df) || df < 0 || ncp < 0) {
+            return RMathError.defaultError();
+        }
+
+        try {
+            DPQ.rqp01boundaries(pIn, 0, Double.POSITIVE_INFINITY, lowerTail, logP);
+        } catch (EarlyReturn e) {
+            return e.result;
+        }
+
+        double pp = DPQ.rdqiv(pIn, logP);
+        if (pp > 1 - DBL_EPSILON) {
+            return lowerTail ? Double.POSITIVE_INFINITY : 0.0;
+        }
+
+        /*
+         * Invert pnchisq(.) : 1. finding an upper and lower bound
+         */
+
+        /*
+         * This is Pearson's (1959) approximation, which is usually good to 4 figs or so.
+         */
+        double b = (ncp * ncp) / (df + 3 * ncp);
+        double c = (df + 3 * ncp) / (df + 2 * ncp);
+        double ff = (df + 2 * ncp) / (c * c);
+        double ux = b + c * qchisq.evaluate(pIn, ff, lowerTail, logP);
+        if (ux < 0) {
+            ux = 1;
+        }
+        double ux0 = ux;
+
+        double p = pIn;
+        boolean newLowerTail = lowerTail;
+        if (!newLowerTail && ncp >= 80) {
+            /* in this case, pnchisq() works via lower_tail = true */
+            if (pp < 1e-10) {
+                RMathError.error(MLError.PRECISION, "qnchisq");
+            }
+            p = DPQ.rdtqiv(p, newLowerTail, logP);
+            newLowerTail = true;
+        } else {
+            p = pp;
+        }
+
+        pp = RMath.fmin2(1 - DBL_EPSILON, p * (1 + Eps));
+        while (ux < DBL_MAX && isLower(newLowerTail, pnchisq.pnchisqRaw(ux, df, ncp, Eps, rEps, 10000, newLowerTail, false), pp)) {
+            ux *= 2;
+        }
+        pp = p * (1 - Eps);
+        double lx = RMath.fmin2(ux0, DBL_MAX);
+        while (lx > DBL_MIN && isGreater(newLowerTail, pnchisq.pnchisqRaw(lx, df, ncp, Eps, rEps, 10000, newLowerTail, false), pp)) {
+            lx *= 0.5;
+        }
+
+        /* 2. interval (lx,ux) halving : */
+        double nx;
+        do {
+            nx = 0.5 * (lx + ux);
+            double raw = pnchisq.pnchisqRaw(nx, df, ncp, accu, racc, 100000, newLowerTail, false);
+            if (isGreater(newLowerTail, raw, p)) {
+                ux = nx;
+            } else {
+                lx = nx;
+            }
+        } while ((ux - lx) / nx > accu);
+
+        return 0.5 * (ux + lx);
+    }
+
+    /**
+     * Is greater that changes to is lower if {@code lowerTail} is {@code false}.
+     */
+    private boolean isGreater(boolean lowerTail, double raw, double p) {
+        return (lowerTail && raw > p) || (!lowerTail && raw < p);
+    }
+
+    private boolean isLower(boolean lowerTail, double raw, double p) {
+        return (lowerTail && raw < p) || (!lowerTail && raw > p);
+    }
+}
diff --git a/com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/stats/QPois.java b/com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/stats/QPois.java
new file mode 100644
index 0000000000000000000000000000000000000000..95f1096a5de95f3192ba8b7460bf39c22932f149
--- /dev/null
+++ b/com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/stats/QPois.java
@@ -0,0 +1,130 @@
+/*
+ * This material is distributed under the GNU General Public License
+ * Version 2. You may review the terms of this license at
+ * http://www.gnu.org/licenses/gpl-2.0.html
+ *
+ * Copyright (C) 1998 Ross Ihaka
+ * Copyright (c) 2000-2014, The R Core Team
+ * Copyright (c) 2016, Oracle and/or its affiliates
+ *
+ * All rights reserved.
+ */
+package com.oracle.truffle.r.library.stats;
+
+import static com.oracle.truffle.r.library.stats.MathConstants.DBL_EPSILON;
+
+import com.oracle.truffle.r.library.stats.DPQ.EarlyReturn;
+import com.oracle.truffle.r.library.stats.StatsFunctions.Function2_2;
+
+public final class QPois implements Function2_2 {
+    private final Qnorm qnorm = new Qnorm();
+    private final PPois ppois = new PPois();
+
+    @Override
+    public double evaluate(double pIn, double lambda, boolean lowerTail, boolean logP) {
+        if (Double.isNaN(pIn) || Double.isNaN(lambda)) {
+            return pIn + lambda;
+        }
+        if (!Double.isFinite(lambda)) {
+            return RMathError.defaultError();
+        }
+        if (lambda < 0) {
+            return RMathError.defaultError();
+        }
+        if (lambda == 0) {
+            return 0;
+        }
+
+        try {
+            DPQ.rqp01boundaries(pIn, 0, Double.POSITIVE_INFINITY, lowerTail, logP);
+        } catch (EarlyReturn e) {
+            return e.result;
+        }
+
+        double mu = lambda;
+        double sigma = Math.sqrt(lambda);
+        /* gamma = sigma; PR#8058 should be kurtosis which is mu^-0.5 */
+        double gamma = 1.0 / sigma;
+
+        /*
+         * Note : "same" code in qpois.c, qbinom.c, qnbinom.c -- FIXME: This is far from optimal
+         * [cancellation for p ~= 1, etc]:
+         */
+        double p = pIn;
+        if (!lowerTail || logP) {
+            p = DPQ.rdtqiv(p, lowerTail, logP); /* need check again (cancellation!): */
+            if (p == 0.) {
+                return 0;
+            }
+            if (p == 1.) {
+                return Double.POSITIVE_INFINITY;
+            }
+        }
+        /* temporary hack --- FIXME --- */
+        if (p + 1.01 * DBL_EPSILON >= 1.) {
+            return Double.POSITIVE_INFINITY;
+        }
+
+        /* y := approx.value (Cornish-Fisher expansion) : */
+        double z = qnorm.evaluate(p, 0., 1., /* lower_tail */true, /* log_p */false);
+        // #ifdef HAVE_NEARBYINT
+        // y = nearbyint(mu + sigma * (z + gamma * (z*z - 1) / 6));
+        // #else
+        double y = Math.round(mu + sigma * (z + gamma * (z * z - 1) / 6));
+
+        z = ppois.evaluate(y, lambda, /* lower_tail */true, /* log_p */false);
+
+        /* fuzz to ensure left continuity; 1 - 1e-7 may lose too much : */
+        p *= 1 - 64 * DBL_EPSILON;
+
+        /* If the mean is not too large a simple search is OK */
+        if (lambda < 1e5) {
+            return search(y, z, p, lambda, 1).y;
+        } else {
+            /* Otherwise be a bit cleverer in the search */
+            double incr = Math.floor(y * 0.001);
+            double oldincr;
+            do {
+                oldincr = incr;
+                SearchResult searchResult = search(y, z, p, lambda, incr);
+                y = searchResult.y;
+                z = searchResult.z;
+                incr = RMath.fmax2(1, Math.floor(incr / 100));
+            } while (oldincr > 1 && incr > lambda * 1e-15);
+            return y;
+        }
+    }
+
+    private SearchResult search(double yIn, double zIn, double p, double lambda, double incr) {
+        if (zIn >= p) {
+            /* search to the left */
+            double y = yIn;
+            for (;;) {
+                double z = zIn;
+                if (y == 0 || (z = ppois.evaluate(y - incr, lambda, /* l._t. */true, /* log_p */false)) < p) {
+                    return new SearchResult(y, z);
+                }
+                y = RMath.fmax2(0, y - incr);
+            }
+        } else { /* search to the right */
+            double y = yIn;
+            for (;;) {
+                y = y + incr;
+                double z;
+                if ((z = ppois.evaluate(y, lambda, /* l._t. */true, /* log_p */false)) >= p) {
+                    return new SearchResult(y, z);
+                }
+            }
+        }
+    }
+
+    private static final class SearchResult {
+        final double y;
+        final double z;
+
+        SearchResult(double y, double z) {
+            this.y = y;
+            this.z = z;
+        }
+    }
+}
diff --git a/com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/stats/Qf.java b/com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/stats/Qf.java
new file mode 100644
index 0000000000000000000000000000000000000000..94d0967d1c800f55b0e4636aa4d8d84f5c178279
--- /dev/null
+++ b/com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/stats/Qf.java
@@ -0,0 +1,60 @@
+/*
+ * This material is distributed under the GNU General Public License
+ * Version 2. You may review the terms of this license at
+ * http://www.gnu.org/licenses/gpl-2.0.html
+ *
+ * Copyright (C) 1998 Ross Ihaka
+ * Copyright (c) 2000--2015, The R Core Team
+ * Copyright (c) 2005, The R Foundation
+ * Copyright (c) 2016, Oracle and/or its affiliates
+ *
+ * All rights reserved.
+ */
+package com.oracle.truffle.r.library.stats;
+
+import com.oracle.truffle.r.library.stats.Chisq.QChisq;
+import com.oracle.truffle.r.library.stats.DPQ.EarlyReturn;
+import com.oracle.truffle.r.library.stats.StatsFunctions.Function3_2;
+
+public final class Qf implements Function3_2 {
+    private final QBeta qbeta = new QBeta();
+    private final QChisq qchisq = new QChisq();
+
+    @Override
+    public double evaluate(double p, double df1, double df2, boolean lowerTail, boolean logP) {
+
+        if (Double.isNaN(p) || Double.isNaN(df1) || Double.isNaN(df2)) {
+            return p + df1 + df2;
+        }
+
+        if (df1 <= 0. || df2 <= 0.) {
+            return RMathError.defaultError();
+        }
+
+        try {
+            DPQ.rqp01boundaries(p, 0, Double.POSITIVE_INFINITY, lowerTail, logP);
+        } catch (EarlyReturn e) {
+            return e.result;
+        }
+
+        /*
+         * fudge the extreme DF cases -- qbeta doesn't do this well. But we still need to fudge the
+         * infinite ones.
+         */
+
+        if (df1 <= df2 && df2 > 4e5) {
+            if (!Double.isFinite(df1)) { /* df1 == df2 == Inf : */
+                return 1.;
+            } else {
+                return qchisq.evaluate(p, df1, lowerTail, logP) / df1;
+            }
+        }
+        if (df1 > 4e5) { /* and so df2 < df1 */
+            return df2 / qchisq.evaluate(p, df2, !lowerTail, logP);
+        }
+
+        // FIXME: (1/qb - 1) = (1 - qb)/qb; if we know qb ~= 1, should use other tail
+        double newP = (1. / qbeta.evaluate(p, df2 / 2, df1 / 2, !lowerTail, logP) - 1.) * (df2 / df1);
+        return RMath.mlValid(newP) ? newP : Double.NaN;
+    }
+}
diff --git a/com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/stats/Qnf.java b/com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/stats/Qnf.java
new file mode 100644
index 0000000000000000000000000000000000000000..54a6acf636c3f2224d467dd98b754912cff380ea
--- /dev/null
+++ b/com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/stats/Qnf.java
@@ -0,0 +1,43 @@
+/*
+ * This material is distributed under the GNU General Public License
+ * Version 2. You may review the terms of this license at
+ * http://www.gnu.org/licenses/gpl-2.0.html
+ *
+ * Copyright (c) 2006-8, The R Core Team
+ * Copyright (c) 2016, Oracle and/or its affiliates
+ *
+ * All rights reserved.
+ */
+package com.oracle.truffle.r.library.stats;
+
+import com.oracle.truffle.r.library.stats.DPQ.EarlyReturn;
+import com.oracle.truffle.r.library.stats.StatsFunctions.Function4_2;
+
+public final class Qnf implements Function4_2 {
+    private final QNChisq qnchisq = new QNChisq();
+    private final QNBeta qnbeta = new QNBeta();
+
+    @Override
+    public double evaluate(double p, double df1, double df2, double ncp, boolean lowerTail, boolean logP) {
+        if (Double.isNaN(p) || Double.isNaN(df1) || Double.isNaN(df2) || Double.isNaN(ncp)) {
+            return p + df1 + df2 + ncp;
+        }
+        if (df1 <= 0. || df2 <= 0. || ncp < 0 || !Double.isFinite(ncp) || !Double.isFinite(df1) && !Double.isFinite(df2)) {
+            return RMathError.defaultError();
+        }
+
+        try {
+            DPQ.rqp01boundaries(p, 0, Double.POSITIVE_INFINITY, lowerTail, logP);
+        } catch (EarlyReturn e) {
+            return e.result;
+        }
+
+        if (df2 > 1e8) {
+            /* avoid problems with +Inf and loss of accuracy */
+            return qnchisq.evaluate(p, df1, ncp, lowerTail, logP) / df1;
+        }
+
+        double y = qnbeta.evaluate(p, df1 / 2., df2 / 2., ncp, lowerTail, logP);
+        return y / (1 - y) * (df2 / df1);
+    }
+}
diff --git a/com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/stats/Qt.java b/com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/stats/Qt.java
new file mode 100644
index 0000000000000000000000000000000000000000..5c527504357c63d421a371b0f3df14191f277cbd
--- /dev/null
+++ b/com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/stats/Qt.java
@@ -0,0 +1,218 @@
+/*
+ * This material is distributed under the GNU General Public License
+ * Version 2. You may review the terms of this license at
+ * http://www.gnu.org/licenses/gpl-2.0.html
+ *
+ * Copyright (C) 1998 Ross Ihaka
+ * Copyright (c) 2000-2013, The R Core Team
+ * Copyright (c) 2003-2013, The R Foundation
+ * Copyright (c) 2016, Oracle and/or its affiliates
+ *
+ * All rights reserved.
+ */
+package com.oracle.truffle.r.library.stats;
+
+import static com.oracle.truffle.r.library.stats.MathConstants.DBL_EPSILON;
+import static com.oracle.truffle.r.library.stats.MathConstants.DBL_MANT_DIG;
+import static com.oracle.truffle.r.library.stats.MathConstants.DBL_MIN;
+import static com.oracle.truffle.r.library.stats.MathConstants.M_1_PI;
+import static com.oracle.truffle.r.library.stats.MathConstants.M_LN2;
+import static com.oracle.truffle.r.library.stats.MathConstants.M_PI;
+import static com.oracle.truffle.r.library.stats.MathConstants.M_PI_2;
+import static com.oracle.truffle.r.library.stats.MathConstants.M_SQRT2;
+
+import com.oracle.truffle.r.library.stats.DPQ.EarlyReturn;
+import com.oracle.truffle.r.library.stats.StatsFunctions.Function2_2;
+
+public final class Qt implements Function2_2 {
+    private static final double eps = 1.e-12;
+    private static final double accu = 1e-13;
+    private static final double Eps = 1e-11; /* must be > accu */
+
+    private final Qnorm qnorm = new Qnorm();
+    private final Dt dt = new Dt();
+    private final Pt pt = new Pt();
+
+    @Override
+    public double evaluate(double pIn, double ndf, boolean lowerTail, boolean logP) {
+
+        if (Double.isNaN(pIn) || Double.isNaN(ndf)) {
+            return pIn + ndf;
+        }
+
+        try {
+            DPQ.rqp01boundaries(pIn, Double.NEGATIVE_INFINITY, Double.POSITIVE_INFINITY, lowerTail, logP);
+        } catch (EarlyReturn earlyReturn) {
+            return earlyReturn.result;
+        }
+
+        if (ndf <= 0) {
+            return RMathError.defaultError();
+        }
+
+        double p = pIn;
+        if (ndf < 1) { /* based on qnt */
+
+            int iter = 0;
+
+            p = DPQ.rdtqiv(p, lowerTail, logP);
+
+            /*
+             * Invert pt(.) : 1. finding an upper and lower bound
+             */
+            if (p > 1 - DBL_EPSILON) {
+                return Double.POSITIVE_INFINITY;
+            }
+            double pp = RMath.fmin2(1 - DBL_EPSILON, p * (1 + Eps));
+            double ux;
+            double lx;
+            ux = 1.;
+            while (ux < Double.MAX_VALUE && pt.evaluate(ux, ndf, true, false) < pp) {
+                ux *= 2;
+            }
+            pp = p * (1 - Eps);
+            lx = -1.;
+            while (lx > -Double.MAX_VALUE && pt.evaluate(lx, ndf, true, false) > pp) {
+                lx *= 2;
+            }
+
+            /*
+             * 2. interval (lx,ux) halving regula falsi failed on qt(0.1, 0.1)
+             */
+            double nx;
+            do {
+                nx = 0.5 * (lx + ux);
+                if (pt.evaluate(nx, ndf, true, false) > p) {
+                    ux = nx;
+                } else {
+                    lx = nx;
+                }
+            } while ((ux - lx) / Math.abs(nx) > accu && ++iter < 1000);
+
+            if (iter >= 1000) {
+                return RMathError.defaultError();
+            }
+
+            return 0.5 * (lx + ux);
+        }
+
+        if (ndf > 1e20) {
+            return qnorm.evaluate(p, 0., 1., lowerTail, logP);
+        }
+
+        double capP = DPQ.rdqiv(p, logP); /* if Math.exp(p) underflows, we fix below */
+
+        boolean neg = (!lowerTail || capP < 0.5) && (lowerTail || capP > 0.5);
+        boolean isNegLower = (lowerTail == neg); /* both true or false == !xor */
+        if (neg) {
+            capP = 2 * (logP ? (lowerTail ? capP : -RMath.expm1(p)) : DPQ.rdlval(p, lowerTail));
+        } else {
+            capP = 2 * (logP ? (lowerTail ? -RMath.expm1(p) : capP) : DPQ.rdcval(p, lowerTail));
+        }
+        /* 0 <= P <= 1 ; P = 2*min(P', 1 - P') in all cases */
+
+        double q;
+        if (Math.abs(ndf - 2) < eps) { /* df ~= 2 */
+            if (capP > DBL_MIN) {
+                if (3 * capP < DBL_EPSILON) { /* P ~= 0 */
+                    q = 1 / Math.sqrt(capP);
+                } else if (capP > 0.9) { /* P ~= 1 */
+                    q = (1 - capP) * Math.sqrt(2 / (capP * (2 - capP)));
+                } else { /* eps/3 <= P <= 0.9 */
+                    q = Math.sqrt(2 / (capP * (2 - capP)) - 2);
+                }
+            } else { /* P << 1, q = 1/Math.sqrt(P) = ... */
+                if (logP) {
+                    q = isNegLower ? Math.exp(-p / 2) / M_SQRT2 : 1 / Math.sqrt(-RMath.expm1(p));
+                } else {
+                    q = Double.POSITIVE_INFINITY;
+                }
+            }
+        } else if (ndf < 1 + eps) { /* df ~= 1 (df < 1 excluded above): Cauchy */
+            if (capP == 1.) {
+                q = 0;
+            } else if (capP > 0) {
+                // some versions of tanpi give Inf, some NaN
+                q = 1 / RMath.tanpi(capP / 2.); /* == - tan((P+1) * M_PI_2) -- suffers for P ~= 0 */
+            } else { /* P = 0, but maybe = 2*Math.exp(p) ! */
+                if (logP) { /* 1/tan(e) ~ 1/e */
+                    q = isNegLower ? M_1_PI * Math.exp(-p) : -1. / (M_PI * RMath.expm1(p));
+                } else {
+                    q = Double.POSITIVE_INFINITY;
+                }
+            }
+        } else { /*-- usual case;  including, e.g.,  df = 1.1 */
+            double x = 0.;
+            double y = 0;
+            double logP2 = 0.;
+            double a = 1 / (ndf - 0.5);
+            double b = 48 / (a * a);
+            double c = ((20700 * a / b - 98) * a - 16) * a + 96.36;
+            double d = ((94.5 / (b + c) - 3) / b + 1) * Math.sqrt(a * M_PI_2) * ndf;
+
+            boolean pOk1 = capP > DBL_MIN || !logP;
+            boolean pOk = pOk1;
+            if (pOk1) {
+                y = Math.pow(d * capP, 2.0 / ndf);
+                pOk = (y >= DBL_EPSILON);
+            }
+            if (!pOk) { // log.p && P very.small || (d*P)^(2/df) =: y < eps_c
+                logP2 = isNegLower ? DPQ.rdlog(p, logP) : DPQ.rdlexp(p, logP); /*
+                                                                                * == Math.log(P / 2)
+                                                                                */
+                x = (Math.log(d) + M_LN2 + logP2) / ndf;
+                y = Math.exp(2 * x);
+            }
+
+            if ((ndf < 2.1 && capP > 0.5) || y > 0.05 + a) { /* P > P0(df) */
+                /* Asymptotic inverse expansion about normal */
+                if (pOk) {
+                    x = qnorm.evaluate(0.5 * capP, 0., 1., /* lower_tail */true, /* log_p */false);
+                } else { /* log_p && P underflowed */
+                    x = qnorm.evaluate(logP2, 0., 1., lowerTail, /* log_p */ true);
+                }
+
+                y = x * x;
+                if (ndf < 5) {
+                    c += 0.3 * (ndf - 4.5) * (x + 0.6);
+                }
+                c = (((0.05 * d * x - 5) * x - 7) * x - 2) * x + b + c;
+                y = (((((0.4 * y + 6.3) * y + 36) * y + 94.5) / c - y - 3) / b + 1) * x;
+                y = RMath.expm1(a * y * y);
+                q = Math.sqrt(ndf * y);
+            } else if (!pOk && x < -M_LN2 * DBL_MANT_DIG) { /* 0.5* Math.log(DBL_EPSILON) */
+                /* y above might have underflown */
+                q = Math.sqrt(ndf) * Math.exp(-x);
+            } else { /* re-use 'y' from above */
+                y = ((1 / (((ndf + 6) / (ndf * y) - 0.089 * d - 0.822) * (ndf + 2) * 3) + 0.5 / (ndf + 4)) * y - 1) * (ndf + 1) / (ndf + 2) + 1 / y;
+                q = Math.sqrt(ndf * y);
+            }
+
+            /*
+             * Now apply 2-term Taylor expansion improvement (1-term = Newton): as by Hill (1981)
+             * [ref.above]
+             */
+
+            /*
+             * FIXME: This can be far from optimal when log_p = true but is still needed, e.g. for
+             * qt(-2, df=1.01, log=true). Probably also improvable when lower_tail = false
+             */
+
+            if (pOk1) {
+                int it = 0;
+                while (it++ < 10 && (y = dt.evaluate(q, ndf, false)) > 0 &&
+                                Double.isFinite(x = (pt.evaluate(q, ndf, false, false) - capP / 2) / y) &&
+                                Math.abs(x) > 1e-14 * Math.abs(q)) {
+                    /*
+                     * Newton (=Taylor 1 term): q += x; Taylor 2-term :
+                     */
+                    q += x * (1. + x * q * (ndf + 1) / (2 * (q * q + ndf)));
+                }
+            }
+        }
+        if (neg) {
+            q = -q;
+        }
+        return q;
+    }
+}
diff --git a/com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/stats/RBeta.java b/com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/stats/RBeta.java
index d62ab89e7e74c7d8962352525c10588f022e4c2d..cc59560caa6b01c6559d67e1f37e6559e0e4e3ea 100644
--- a/com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/stats/RBeta.java
+++ b/com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/stats/RBeta.java
@@ -20,14 +20,23 @@ import static com.oracle.truffle.r.library.stats.RMath.fmin2;
 import com.oracle.truffle.r.library.stats.RandGenerationFunctions.RandFunction2_Double;
 import com.oracle.truffle.r.library.stats.RandGenerationFunctions.RandomNumberProvider;
 
-public final class RBeta implements RandFunction2_Double {
+public final class RBeta extends RandFunction2_Double {
 
     private static final double expmax = (DBL_MAX_EXP * M_LN2); /* = log(DBL_MAX) */
 
+    // TODO: state variables
+    private static double beta = 0;
+    private static double gamma = 1;
+    private static double delta;
+    private static double k1 = 0;
+    private static double k2 = 0;
+    private static double olda = -1.0;
+    private static double oldb = -1.0;
+
     @Override
-    public double evaluate(double aa, double bb, RandomNumberProvider rand) {
+    public double execute(double aa, double bb, RandomNumberProvider rand) {
         if (Double.isNaN(aa) || Double.isNaN(bb) || aa < 0. || bb < 0.) {
-            return RMath.mlError();
+            return RMathError.defaultError();
         }
         if (!Double.isFinite(aa) && !Double.isFinite(bb)) { // a = b = Inf : all mass at 1/2
             return 0.5;
@@ -43,27 +52,6 @@ public final class RBeta implements RandFunction2_Double {
             return 0.0;
         }
 
-        double a;
-        double b;
-        double r;
-        double s;
-        double t;
-        double u1;
-        double u2;
-        double v = 0;
-        double w = 0;
-        double y;
-        double z;
-
-        // TODO: state variables
-        double beta = 0;
-        double gamma = 1;
-        double delta;
-        double k1 = 0;
-        double k2 = 0;
-        double olda = -1.0;
-        double oldb = -1.0;
-
         /* Test if we need new "initializing" */
         boolean qsame = (olda == aa) && (oldb == bb);
         if (!qsame) {
@@ -71,10 +59,13 @@ public final class RBeta implements RandFunction2_Double {
             oldb = bb;
         }
 
-        a = fmin2(aa, bb);
-        b = fmax2(aa, bb); /* a <= b */
+        double a = fmin2(aa, bb);
+        double b = fmax2(aa, bb); /* a <= b */
         double alpha = a + b;
 
+        double v;
+        double w;
+
         if (a <= 1.0) { /* --- Algorithm BC --- */
             /* changed notation, now also a <= b (was reversed) */
             if (!qsame) { /* initialize */
@@ -85,10 +76,11 @@ public final class RBeta implements RandFunction2_Double {
             }
             /* FIXME: "do { } while()", but not trivially because of "continue"s: */
             for (;;) {
-                u1 = rand.unifRand();
-                u2 = rand.unifRand();
+                double u1 = rand.unifRand();
+                double u2 = rand.unifRand();
+                double z;
                 if (u1 < 0.5) {
-                    y = u1 * u2;
+                    double y = u1 * u2;
                     z = u1 * y;
                     if (0.25 * u2 + z - y >= k1) {
                         continue;
@@ -97,7 +89,7 @@ public final class RBeta implements RandFunction2_Double {
                     z = u1 * u1 * u2;
                     if (z <= 0.25) {
                         v = beta * Math.log(u1 / (1.0 - u1));
-                        w = wFromU1Bet(b, v, w);
+                        w = wFromU1Bet(b, v);
                         break;
                     }
                     if (z >= k2) {
@@ -106,7 +98,7 @@ public final class RBeta implements RandFunction2_Double {
                 }
 
                 v = beta * Math.log(u1 / (1.0 - u1));
-                w = wFromU1Bet(b, v, w);
+                w = wFromU1Bet(b, v);
 
                 if (alpha * (Math.log(alpha / (a + w)) + v) - 1.3862944 >= Math.log(z)) {
                     break;
@@ -120,16 +112,18 @@ public final class RBeta implements RandFunction2_Double {
                 beta = Math.sqrt((alpha - 2.0) / (2.0 * a * b - alpha));
                 gamma = a + 1.0 / beta;
             }
+            double r;
+            double t;
             do {
-                u1 = rand.unifRand();
-                u2 = rand.unifRand();
+                double u1 = rand.unifRand();
+                double u2 = rand.unifRand();
 
                 v = beta * Math.log(u1 / (1.0 - u1));
-                w = wFromU1Bet(a, v, w);
+                w = wFromU1Bet(a, v);
 
-                z = u1 * u1 * u2;
+                double z = u1 * u1 * u2;
                 r = gamma * v - 1.3862944;
-                s = a + r - w;
+                double s = a + r - w;
                 if (s + 2.609438 >= 5.0 * z) {
                     break;
                 }
@@ -143,16 +137,13 @@ public final class RBeta implements RandFunction2_Double {
         }
     }
 
-    private static double wFromU1Bet(double aa, double v, double w) {
+    private static double wFromU1Bet(double aa, double v) {
         if (v <= expmax) {
-            w = aa * Math.exp(v);
-            if (!Double.isFinite(w)) {
-                w = Double.MAX_VALUE;
-            }
+            double result = aa * Math.exp(v);
+            return Double.isFinite(result) ? result : Double.MAX_VALUE;
         } else {
-            w = Double.MAX_VALUE;
+            return Double.MAX_VALUE;
         }
-        return w;
     }
 
 }
diff --git a/com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/stats/RChisq.java b/com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/stats/RChisq.java
deleted file mode 100644
index 67ba496753caf017b672e0003654a11f1eb4904d..0000000000000000000000000000000000000000
--- a/com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/stats/RChisq.java
+++ /dev/null
@@ -1,29 +0,0 @@
-/*
- * This material is distributed under the GNU General Public License
- * Version 2. You may review the terms of this license at
- * http://www.gnu.org/licenses/gpl-2.0.html
- *
- * Copyright (C) 1998 Ross Ihaka
- * Copyright (c) 1998--2008, The R Core Team
- * Copyright (c) 2016, 2016, Oracle and/or its affiliates
- *
- * All rights reserved.
- */
-package com.oracle.truffle.r.library.stats;
-
-import com.oracle.truffle.r.library.stats.RandGenerationFunctions.RandFunction1_Double;
-import com.oracle.truffle.r.library.stats.RandGenerationFunctions.RandomNumberProvider;
-
-public final class RChisq implements RandFunction1_Double {
-    public static double rchisq(double df, RandomNumberProvider rand) {
-        if (!Double.isFinite(df) || df < 0.0) {
-            return RMath.mlError();
-        }
-        return new RGamma().evaluate(df / 2.0, 2.0, rand);
-    }
-
-    @Override
-    public double evaluate(double a, RandomNumberProvider rand) {
-        return rchisq(a, rand);
-    }
-}
diff --git a/com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/stats/RGamma.java b/com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/stats/RGamma.java
index eea9b5aea8027a913db009a0f96260fa22327fed..f3546d5e1a7b174d106d48e902dfef71e6a1aa83 100644
--- a/com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/stats/RGamma.java
+++ b/com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/stats/RGamma.java
@@ -16,7 +16,7 @@ import static com.oracle.truffle.r.library.stats.TOMS708.fabs;
 import com.oracle.truffle.r.library.stats.RandGenerationFunctions.RandFunction2_Double;
 import com.oracle.truffle.r.library.stats.RandGenerationFunctions.RandomNumberProvider;
 
-public class RGamma implements RandFunction2_Double {
+public final class RGamma extends RandFunction2_Double {
     private static final double sqrt32 = 5.656854;
     private static final double exp_m1 = 0.36787944117144232159; /* exp(-1) = 1/e */
 
@@ -41,11 +41,11 @@ public class RGamma implements RandFunction2_Double {
     private static final double a7 = 0.1233795;
 
     @Override
-    public double evaluate(double a, double scale, RandomNumberProvider rand) {
+    public double execute(double a, double scale, RandomNumberProvider rand) {
 
         // TODO: state variables
-        double aa = 0.;
-        double aaa = 0.;
+        double aa = Double.NaN;
+        double aaa = Double.NaN;
         double s = 0;
         double s2 = 0;
         double d = 0; /* no. 1 (step 1) */
@@ -66,13 +66,13 @@ public class RGamma implements RandFunction2_Double {
         double retVal;
 
         if (Double.isNaN(a) || Double.isNaN(scale)) {
-            return RMath.mlError();
+            return RMathError.defaultError();
         }
         if (a <= 0.0 || scale <= 0.0) {
             if (scale == 0. || a == 0.) {
                 return 0.;
             }
-            return RMath.mlError();
+            return RMathError.defaultError();
         }
         if (!Double.isFinite(a) || !Double.isFinite(scale)) {
             return Double.POSITIVE_INFINITY;
diff --git a/com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/stats/RHyper.java b/com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/stats/RHyper.java
index 7dba16badee221972e01340629a88e35ffe0a1b1..fb549a90f9e39d7262d5793b9ef3b3cdff6ddfe4 100644
--- a/com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/stats/RHyper.java
+++ b/com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/stats/RHyper.java
@@ -13,7 +13,7 @@
 package com.oracle.truffle.r.library.stats;
 
 import static com.oracle.truffle.r.library.stats.MathConstants.M_LN_SQRT_2PI;
-import static com.oracle.truffle.r.library.stats.MathConstants.forceint;
+import static com.oracle.truffle.r.library.stats.RMath.forceint;
 
 import com.oracle.truffle.api.CompilerDirectives.TruffleBoundary;
 import com.oracle.truffle.r.library.stats.RandGenerationFunctions.RandFunction3_Double;
@@ -21,7 +21,7 @@ import com.oracle.truffle.r.library.stats.RandGenerationFunctions.RandomNumberPr
 import com.oracle.truffle.r.runtime.RError;
 import com.oracle.truffle.r.runtime.RError.Message;
 
-public final class RHyper implements RandFunction3_Double {
+public final class RHyper extends RandFunction3_Double {
     private static final double[] al = {
                     0.0, /* ln(0!)=ln(1) */
                     0.0, /* ln(1!)=ln(1) */
@@ -34,7 +34,7 @@ public final class RHyper implements RandFunction3_Double {
                     /*
                      * 10.60460290274525022841722740072165, approx. value below = 10.6046028788027;
                      * rel.error = 2.26 10^{-9}
-                     * 
+                     *
                      * FIXME: Use constants and if(n > ..) decisions from ./stirlerr.c ----- will be
                      * even *faster* for n > 500 (or so)
                      */
@@ -73,7 +73,14 @@ public final class RHyper implements RandFunction3_Double {
     private static double w;
     // III:
     // Checkstyle: stop
-    private static double a, d, s, xl, xr, kl, kr, lamdl, lamdr, p1, p2, p3;
+    private static double a;
+    private static double xl;
+    private static double xr;
+    private static double lamdl;
+    private static double lamdr;
+    private static double p1;
+    private static double p2;
+    private static double p3;
     // // Checkstyle: resume
 
     private static final double scale = 1e25; // scaling factor against (early) underflow
@@ -87,46 +94,43 @@ public final class RHyper implements RandFunction3_Double {
     // rhyper(NR, NB, n) -- NR 'red', NB 'blue', n drawn, how many are 'red'
     @Override
     @TruffleBoundary
-    public double evaluate(double nn1in, double nn2in, double kkin, RandomNumberProvider rand) {
+    public double execute(double nn1in, double nn2in, double kkin, RandomNumberProvider rand) {
         /* extern double afc(int); */
 
-        int nn1;
-        int nn2;
-        int kk;
         int ix; // return value (coerced to double at the very end)
-        boolean setup1;
-        boolean setup2;
 
         /* check parameter validity */
 
         if (!Double.isFinite(nn1in) || !Double.isFinite(nn2in) || !Double.isFinite(kkin)) {
-            return RMath.mlError();
+            return RMathError.defaultError();
         }
 
-        nn1in = forceint(nn1in);
-        nn2in = forceint(nn2in);
-        kkin = forceint(kkin);
+        double nn1int = forceint(nn1in);
+        double nn2int = forceint(nn2in);
+        double kkint = forceint(kkin);
 
-        if (nn1in < 0 || nn2in < 0 || kkin < 0 || kkin > nn1in + nn2in) {
-            return RMath.mlError();
+        if (nn1int < 0 || nn2int < 0 || kkint < 0 || kkint > nn1int + nn2int) {
+            return RMathError.defaultError();
         }
-        if (nn1in >= Integer.MAX_VALUE || nn2in >= Integer.MAX_VALUE || kkin >= Integer.MAX_VALUE) {
+        if (nn1int >= Integer.MAX_VALUE || nn2int >= Integer.MAX_VALUE || kkint >= Integer.MAX_VALUE) {
             /*
              * large n -- evade integer overflow (and inappropriate algorithms) --------
              */
             // FIXME: Much faster to give rbinom() approx when appropriate; -> see Kuensch(1989)
             // Johnson, Kotz,.. p.258 (top) mention the *four* different binomial approximations
-            if (kkin == 1.) { // Bernoulli
-                return rbinom.evaluate(kkin, nn1in / (nn1in + nn2in), rand);
+            if (kkint == 1.) { // Bernoulli
+                return rbinom.execute(kkint, nn1int / (nn1int + nn2int), rand);
             }
             // Slow, but safe: return F^{-1}(U) where F(.) = phyper(.) and U ~ U[0,1]
-            return QHyper.qhyper(rand.unifRand(), nn1in, nn2in, kkin, false, false);
+            return QHyper.qhyper(rand.unifRand(), nn1int, nn2int, kkint, false, false);
         }
-        nn1 = (int) nn1in;
-        nn2 = (int) nn2in;
-        kk = (int) kkin;
+        int nn1 = (int) nn1int;
+        int nn2 = (int) nn2int;
+        int kk = (int) kkint;
 
         /* if new parameter values, initialize */
+        boolean setup1;
+        boolean setup2;
         if (nn1 != n1s || nn2 != n2s) {
             setup1 = true;
             setup2 = true;
@@ -204,18 +208,19 @@ public final class RHyper implements RandFunction3_Double {
             double u;
             double v;
 
+            double s;
             if (setup1 || setup2) {
                 s = Math.sqrt((tn - k) * k * n1 * n2 / (tn - 1) / tn / tn);
 
                 /* remark: d is defined in reference without int. */
                 /* the truncation centers the cell boundaries at 0.5 */
 
-                d = (int) (1.5 * s) + .5;
+                double d = (int) (1.5 * s) + .5;
                 xl = m - d + .5;
                 xr = m + d + .5;
                 a = afc(m) + afc(n1 - m) + afc(k - m) + afc(n2 - k + m);
-                kl = Math.exp(a - afc((int) (xl)) - afc((int) (n1 - xl)) - afc((int) (k - xl)) - afc((int) (n2 - k + xl)));
-                kr = Math.exp(a - afc((int) (xr - 1)) - afc((int) (n1 - xr + 1)) - afc((int) (k - xr + 1)) - afc((int) (n2 - k + xr - 1)));
+                double kl = Math.exp(a - afc((int) (xl)) - afc((int) (n1 - xl)) - afc((int) (k - xl)) - afc((int) (n2 - k + xl)));
+                double kr = Math.exp(a - afc((int) (xr - 1)) - afc((int) (n1 - xr + 1)) - afc((int) (k - xr + 1)) - afc((int) (n2 - k + xr - 1)));
                 lamdl = -Math.log(xl * (n2 - k + xl) / (n1 - xl + 1) / (k - xl + 1));
                 lamdr = -Math.log((n1 - xr + 1) * (k - xr + 1) / xr / (n2 - k + xr));
                 p1 = d + d;
@@ -230,7 +235,7 @@ public final class RHyper implements RandFunction3_Double {
                 nUv++;
                 if (nUv >= 10000) {
                     RError.warning(RError.SHOW_CALLER, Message.GENERIC, String.format("rhyper() branch III: giving up after %d rejections", nUv));
-                    return RMath.mlError();
+                    return RMathError.defaultError();
                 }
 
                 if (u < p1) { /* rectangular region */
@@ -332,11 +337,7 @@ public final class RHyper implements RandFunction3_Double {
                             /*
                              * * Stirling's formula to machine accuracy
                              */
-                            if (alv <= (a - afc(ix) - afc(n1 - ix) - afc(k - ix) - afc(n2 - k + ix))) {
-                                reject = false;
-                            } else {
-                                reject = true;
-                            }
+                            reject = !(alv <= (a - afc(ix) - afc(n1 - ix) - afc(k - ix) - afc(n2 - k + ix)));
                         }
                     }
                 } // else
@@ -352,11 +353,11 @@ public final class RHyper implements RandFunction3_Double {
             if ((double) nn1 > (double) nn2) {
                 ix1 = (double) kk - (double) nn2 + ix1;
             } else {
-                ix1 = (double) nn1 - ix1;
+                ix1 = nn1 - ix1;
             }
         } else {
             if ((double) nn1 > (double) nn2) {
-                ix1 = (double) kk - ix1;
+                ix1 = kk - ix1;
             }
         }
         return ix1;
diff --git a/com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/stats/RLogis.java b/com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/stats/RLogis.java
deleted file mode 100644
index 961dafe00d10a34156926a5b54379f5510e45ebc..0000000000000000000000000000000000000000
--- a/com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/stats/RLogis.java
+++ /dev/null
@@ -1,31 +0,0 @@
-/*
- * This material is distributed under the GNU General Public License
- * Version 2. You may review the terms of this license at
- * http://www.gnu.org/licenses/gpl-2.0.html
- *
- * Copyright (C) 1998 Ross Ihaka
- * Copyright (c) 1998--2008, The R Core Team
- * Copyright (c) 2016, 2016, Oracle and/or its affiliates
- *
- * All rights reserved.
- */
-package com.oracle.truffle.r.library.stats;
-
-import com.oracle.truffle.r.library.stats.RandGenerationFunctions.RandFunction2_Double;
-import com.oracle.truffle.r.library.stats.RandGenerationFunctions.RandomNumberProvider;
-
-public final class RLogis implements RandFunction2_Double {
-    @Override
-    public double evaluate(double location, double scale, RandomNumberProvider rand) {
-        if (Double.isNaN(location) || !Double.isFinite(scale)) {
-            return RMath.mlError();
-        }
-
-        if (scale == 0. || !Double.isFinite(location)) {
-            return location;
-        } else {
-            double u = rand.unifRand();
-            return location + scale * Math.log(u / (1. - u));
-        }
-    }
-}
diff --git a/com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/stats/RMath.java b/com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/stats/RMath.java
index 7b0d2a4c0dc0e158da8cfad77148cfff9c3028fe..68347359d023a0f292c66d2618558cbe1c009954 100644
--- a/com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/stats/RMath.java
+++ b/com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/stats/RMath.java
@@ -20,23 +20,35 @@ import com.oracle.truffle.r.runtime.RRuntime;
 
 /**
  * Encapsulates functions to be found in Rmath.h or in nmath directory in GnuR except for random
- * distribution related functions, which usually have their own files.
+ * distribution related functions, which usually have their own files, and other well defined groups
+ * of functions/macros referenced below.
  *
  * @see DPQ
+ * @see RMathError
+ * @see MathConstants
  */
-public class RMath {
+public final class RMath {
 
-    /**
-     * corresponds to macro {@code ML_ERR_return_NAN} in GnuR.
-     */
-    public static double mlError() {
-        return Double.NaN;
+    public static boolean mlValid(double d) {
+        return !Double.isNaN(d);
     }
 
     public static double lfastchoose(double n, double k) {
         return -Math.log(n + 1.) - lbeta(n - k + 1., k + 1.);
     }
 
+    /**
+     * Implementation of {@code R_forceint}, which is not equal to {@code Math.round}, because it
+     * returns {@code double} and so it can handle values that do not fit into long.
+     */
+    public static double forceint(double x) {
+        // Note: in GnuR this is alias for nearbyint
+        if (Double.isNaN(x)) {
+            return 0;
+        }
+        return Math.floor(x + 0.5);
+    }
+
     public static double fsign(double x, double y) {
         if (Double.isNaN(x) || Double.isNaN(y)) {
             return x + y;
@@ -44,7 +56,7 @@ public class RMath {
         return ((y >= 0) ? TOMS708.fabs(x) : -TOMS708.fabs(x));
     }
 
-    public static double fmod(double a, double b) {
+    private static double fmod(double a, double b) {
         double q = a / b;
         if (b != 0) {
             double tmp = a - Math.floor(q) * b;
@@ -63,17 +75,17 @@ public class RMath {
             return x;
         }
         if (!Double.isFinite(x)) {
-            return mlError();
+            return RMathError.defaultError();
         }
 
-        x = fmod(x, 1.); // tan(pi(x + k)) == tan(pi x) for all integer k
+        double x2 = fmod(x, 1.); // tan(pi(x + k)) == tan(pi x) for all integer k
         // map (-1,1) --> (-1/2, 1/2] :
-        if (x <= -0.5) {
-            x++;
-        } else if (x > 0.5) {
-            x--;
+        if (x2 <= -0.5) {
+            x2++;
+        } else if (x2 > 0.5) {
+            x2--;
         }
-        return (x == 0.) ? 0. : ((x == 0.5) ? Double.NaN : Math.tan(MathConstants.M_PI * x));
+        return (x2 == 0.) ? 0. : ((x2 == 0.5) ? Double.NaN : Math.tan(MathConstants.M_PI * x2));
     }
 
     //
diff --git a/com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/stats/RMathError.java b/com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/stats/RMathError.java
new file mode 100644
index 0000000000000000000000000000000000000000..31ab7145dccb5391f74d7fc05f509526ba73d2e7
--- /dev/null
+++ b/com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/stats/RMathError.java
@@ -0,0 +1,70 @@
+/*
+ * This material is distributed under the GNU General Public License
+ * Version 2. You may review the terms of this license at
+ * http://www.gnu.org/licenses/gpl-2.0.html
+ *
+ * Copyright (c) 1998-2016, The R Core Team
+ * Copyright (c) 2016, Oracle and/or its affiliates
+ *
+ * All rights reserved.
+ */
+package com.oracle.truffle.r.library.stats;
+
+import com.oracle.truffle.r.runtime.RError;
+import com.oracle.truffle.r.runtime.RError.Message;
+
+/**
+ * Encapsulates functionality related to errors/warnings reporting in FastR port of R's math
+ * library. Contains methods that correspond to various macros such as {@code ML_ERROR} or
+ * {@code ML_ERR_return_NAN}.
+ */
+public final class RMathError {
+    private RMathError() {
+        // only static members
+    }
+
+    public enum MLError {
+        DOMAIN(Message.GENERIC),
+        RANGE(Message.ML_ERROR_RANGE),
+        NOCONV(Message.ML_ERROR_NOCONV),
+        PRECISION(Message.ML_ERROR_PRECISION),
+        UNDERFLOW(Message.ML_ERROR_UNDERFLOW);
+
+        private final RError.Message message;
+
+        MLError(Message message) {
+            this.message = message;
+        }
+
+        public void warning(String arg) {
+            RError.warning(RError.SHOW_CALLER, message, arg);
+        }
+    }
+
+    /**
+     * Corresponds to macro {@code ML_ERR_return_NAN} in GnuR. We also do not report the default
+     * warning directly and let the caller handle the {@code NaN} value.
+     */
+    public static double defaultError() {
+        return Double.NaN;
+    }
+
+    /**
+     * Corresponds to macro {@code ML_ERR} in GnuR. As long as the error is not the default
+     * {@link MLError#DOMAIN} a warning is reported by this method, otherwise the caller should
+     * return {@code NaN}, which should be handled by the caller's caller.
+     */
+    public static double error(@SuppressWarnings("unused") MLError error, @SuppressWarnings("unused") String messageArg) {
+        if (error != MLError.DOMAIN) {
+            error.warning(messageArg);
+        }
+        return Double.NaN;
+    }
+
+    /**
+     * Corresponds to macros {@code MATHLIB_WARNINGX} in GnuR.
+     */
+    public static void warning(RError.Message message, Object... args) {
+        RError.warning(RError.SHOW_CALLER, message, args);
+    }
+}
diff --git a/com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/stats/RMultinom.java b/com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/stats/RMultinom.java
index 7a49a79e36cf75d48bb04762daeac1bb7e791042..9a0f80cd9a3702d9990ca94a00aeb02b60e4c37a 100644
--- a/com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/stats/RMultinom.java
+++ b/com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/stats/RMultinom.java
@@ -29,10 +29,10 @@ import com.oracle.truffle.api.profiles.ValueProfile;
 import com.oracle.truffle.r.library.stats.RandGenerationFunctions.RandomNumberProvider;
 import com.oracle.truffle.r.nodes.attributes.GetFixedAttributeNode;
 import com.oracle.truffle.r.nodes.attributes.SetFixedAttributeNode;
-import com.oracle.truffle.r.nodes.attributes.UpdateSharedAttributeNode;
 import com.oracle.truffle.r.nodes.builtin.CastBuilder;
 import com.oracle.truffle.r.nodes.builtin.RExternalBuiltinNode;
 import com.oracle.truffle.r.nodes.function.opt.ReuseNonSharedNode;
+import com.oracle.truffle.r.nodes.function.opt.UpdateShareableChildValueNode;
 import com.oracle.truffle.r.runtime.RError;
 import com.oracle.truffle.r.runtime.RError.Message;
 import com.oracle.truffle.r.runtime.RRuntime;
@@ -58,7 +58,7 @@ public abstract class RMultinom extends RExternalBuiltinNode.Arg3 {
                     @Cached("create()") ReuseNonSharedNode reuseNonSharedNode,
                     @Cached("createClassProfile()") ValueProfile randGeneratorClassProfile,
                     @Cached("createBinaryProfile()") ConditionProfile hasAttributesProfile,
-                    @Cached("create()") UpdateSharedAttributeNode updateSharedAttributeNode,
+                    @Cached("create()") UpdateShareableChildValueNode updateSharedAttributeNode,
                     @Cached("createNames()") GetFixedAttributeNode getNamesNode,
                     @Cached("createDimNames()") SetFixedAttributeNode setDimNamesNode) {
         RAbstractDoubleVector nonSharedProbs = (RAbstractDoubleVector) reuseNonSharedNode.execute(probsVec);
@@ -89,16 +89,16 @@ public abstract class RMultinom extends RExternalBuiltinNode.Arg3 {
     private static void fixupProb(double[] p) {
         double sum = 0.0;
         int npos = 0;
-        for (int i = 0; i < p.length; i++) {
-            if (!Double.isFinite(p[i])) {
+        for (double prob : p) {
+            if (!Double.isFinite(prob)) {
                 throw RError.error(SHOW_CALLER, NA_IN_PROB_VECTOR);
             }
-            if (p[i] < 0.0) {
+            if (prob < 0.0) {
                 throw RError.error(SHOW_CALLER, NEGATIVE_PROBABILITY);
             }
-            if (p[i] > 0.0) {
+            if (prob > 0.0) {
                 npos++;
-                sum += p[i];
+                sum += prob;
             }
         }
         if (npos == 0) {
@@ -115,9 +115,7 @@ public abstract class RMultinom extends RExternalBuiltinNode.Arg3 {
      * prob[j]) , sum_j rN[j] == n, sum_j prob[j] == 1.
      */
     @TruffleBoundary
-    private boolean rmultinom(int n, double[] prob, int maxK, int[] rN, int rnStartIdx, RandomNumberProvider rand) {
-        int k;
-        double pp;
+    private boolean rmultinom(int nIn, double[] prob, int maxK, int[] rN, int rnStartIdx, RandomNumberProvider rand) {
         BigDecimal pTot = BigDecimal.ZERO;
         /*
          * This calculation is sensitive to exact values, so we try to ensure that the calculations
@@ -125,6 +123,7 @@ public abstract class RMultinom extends RExternalBuiltinNode.Arg3 {
          * result.
          */
 
+        int n = nIn;
         if (RRuntime.isNA(maxK) || maxK < 1 || RRuntime.isNA(n) || n < 0) {
             if (rN.length > rnStartIdx) {
                 rN[rnStartIdx] = RRuntime.INT_NA;
@@ -136,8 +135,8 @@ public abstract class RMultinom extends RExternalBuiltinNode.Arg3 {
          * Note: prob[K] is only used here for checking sum_k prob[k] = 1 ; Could make loop one
          * shorter and drop that check !
          */
-        for (k = 0; k < maxK; k++) {
-            pp = prob[k];
+        for (int k = 0; k < maxK; k++) {
+            double pp = prob[k];
             if (!Double.isFinite(pp) || pp < 0. || pp > 1.) {
                 rN[rnStartIdx + k] = RRuntime.INT_NA;
                 return false;
@@ -158,12 +157,12 @@ public abstract class RMultinom extends RExternalBuiltinNode.Arg3 {
         }
 
         /* Generate the first K-1 obs. via binomials */
-        for (k = 0; k < maxK - 1; k++) { /* (p_tot, n) are for "remaining binomial" */
+        for (int k = 0; k < maxK - 1; k++) { /* (p_tot, n) are for "remaining binomial" */
             BigDecimal probK = new BigDecimal(prob[k]);
             if (probK.compareTo(BigDecimal.ZERO) != 0) {
-                pp = probK.divide(pTot, RoundingMode.HALF_UP).doubleValue();
+                double pp = probK.divide(pTot, RoundingMode.HALF_UP).doubleValue();
                 // System.out.printf("[%d] %.17f\n", k + 1, pp);
-                rN[rnStartIdx + k] = ((pp < 1.) ? (int) rbinom.evaluate((double) n, pp, rand) :
+                rN[rnStartIdx + k] = ((pp < 1.) ? (int) rbinom.execute(n, pp, rand) :
                 /* >= 1; > 1 happens because of rounding */
                                 n);
                 n -= rN[rnStartIdx + k];
diff --git a/com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/stats/RNbinomMu.java b/com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/stats/RNbinomMu.java
index c095616fa14e46565ba778fbf3356a6f257ddc66..cf5f8b04016170b0b45f36962c4588980edc39c5 100644
--- a/com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/stats/RNbinomMu.java
+++ b/com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/stats/RNbinomMu.java
@@ -14,17 +14,15 @@ package com.oracle.truffle.r.library.stats;
 import com.oracle.truffle.r.library.stats.RandGenerationFunctions.RandFunction2_Double;
 import com.oracle.truffle.r.library.stats.RandGenerationFunctions.RandomNumberProvider;
 
-public final class RNbinomMu implements RandFunction2_Double {
+public final class RNbinomMu extends RandFunction2_Double {
     private final RGamma rgamma = new RGamma();
 
     @Override
-    public double evaluate(double size, double mu, RandomNumberProvider rand) {
-        if (!Double.isFinite(mu) || Double.isNaN(size) || size <= 0 || mu < 0) {
-            return RMath.mlError();
+    public double execute(double initialSize, double mu, RandomNumberProvider rand) {
+        if (!Double.isFinite(mu) || Double.isNaN(initialSize) || initialSize <= 0 || mu < 0) {
+            return RMathError.defaultError();
         }
-        if (!Double.isFinite(size)) {
-            size = Double.MAX_VALUE / 2.;
-        }
-        return (mu == 0) ? 0 : RPois.rpois(rgamma.evaluate(size, mu / size, rand), rand);
+        double size = Double.isFinite(initialSize) ? initialSize : Double.MAX_VALUE / 2.;
+        return (mu == 0) ? 0 : RPois.rpois(rgamma.execute(size, mu / size, rand), rand);
     }
 }
diff --git a/com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/stats/RNchisq.java b/com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/stats/RNchisq.java
index 5e22bda3f5faf7e3fd655ed596183d3df56e6c07..f0d523cf14d7fd2bccbac019ffeb3d1dfe75a0b0 100644
--- a/com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/stats/RNchisq.java
+++ b/com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/stats/RNchisq.java
@@ -16,24 +16,24 @@ package com.oracle.truffle.r.library.stats;
 import com.oracle.truffle.r.library.stats.RandGenerationFunctions.RandFunction2_Double;
 import com.oracle.truffle.r.library.stats.RandGenerationFunctions.RandomNumberProvider;
 
-public final class RNchisq implements RandFunction2_Double {
+public final class RNchisq extends RandFunction2_Double {
     private final RGamma rgamma = new RGamma();
 
     @Override
-    public double evaluate(double df, double lambda, RandomNumberProvider rand) {
+    public double execute(double df, double lambda, RandomNumberProvider rand) {
         if (!Double.isFinite(df) || !Double.isFinite(lambda) || df < 0. || lambda < 0.) {
-            return RMath.mlError();
+            return RMathError.defaultError();
         }
 
         if (lambda == 0.) {
-            return (df == 0.) ? 0. : rgamma.evaluate(df / 2., 2., rand);
+            return (df == 0.) ? 0. : rgamma.execute(df / 2., 2., rand);
         } else {
             double r = RPois.rpois(lambda / 2., rand);
             if (r > 0.) {
-                r = RChisq.rchisq(2. * r, rand);
+                r = Chisq.RChisq.rchisq(2. * r, rand);
             }
             if (df > 0.) {
-                r += rgamma.evaluate(df / 2., 2., rand);
+                r += rgamma.execute(df / 2., 2., rand);
             }
             return r;
         }
diff --git a/com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/stats/RPois.java b/com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/stats/RPois.java
index 2638fa34de84ce1797d21b9e75acdb4798ab2ba5..36759275c32b8477b5fd67b7a68502abfa804f70 100644
--- a/com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/stats/RPois.java
+++ b/com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/stats/RPois.java
@@ -16,7 +16,7 @@ import static com.oracle.truffle.r.library.stats.MathConstants.M_1_SQRT_2PI;
 import com.oracle.truffle.r.library.stats.RandGenerationFunctions.RandFunction1_Double;
 import com.oracle.truffle.r.library.stats.RandGenerationFunctions.RandomNumberProvider;
 
-public final class RPois implements RandFunction1_Double {
+public final class RPois extends RandFunction1_Double {
 
     private static final double a0 = -0.5;
     private static final double a1 = 0.3333333;
@@ -38,25 +38,23 @@ public final class RPois implements RandFunction1_Double {
 
     /* These are static --- persistent between calls for same mu : */
     // TODO: state variables
-    static int l = 0;
-    static int m = 0;
-    static double b1;
-    static double b2;
-    static double c = 0;
-    static double c0 = 0;
-    static double c1 = 0;
-    static double c2 = 0;
-    static double c3 = 0;
-    static double[] pp = new double[36];
-    static double p0 = 0;
-    static double p = 0;
-    static double q = 0;
-    static double s = 0;
-    static double d = 0;
-    static double omega = 0;
-    static double bigL = 0; /* integer "w/o overflow" */
-    static double muprev = 0.;
-    static double muprev2 = 0.; /* , muold = 0. */
+    private static int l = 0;
+    private static int m = 0;
+    private static double c = 0;
+    private static double c0 = 0;
+    private static double c1 = 0;
+    private static double c2 = 0;
+    private static double c3 = 0;
+    private static final double[] pp = new double[36];
+    private static double p0 = 0;
+    private static double p = 0;
+    private static double q = 0;
+    private static double s = 0;
+    private static double d = 0;
+    private static double omega = 0;
+    private static double bigL = 0; /* integer "w/o overflow" */
+    private static double muprev = 0.;
+    private static double muprev2 = 0.; /* , muold = 0. */
 
     public static double rpois(double mu, RandomNumberProvider rand) {
         /* Local Vars [initialize some for -Wall]: */
@@ -80,7 +78,7 @@ public final class RPois implements RandFunction1_Double {
         boolean newBigMu = false;
 
         if (!Double.isFinite(mu) || mu < 0) {
-            return RMath.mlError();
+            return RMathError.defaultError();
         }
 
         if (mu <= 0.) {
@@ -131,7 +129,7 @@ public final class RPois implements RandFunction1_Double {
                     if (l != 0) {
                         for (k = (u <= 0.458) ? 1 : Math.min(l, m); k <= l; k++) {
                             if (u <= pp[k]) {
-                                return (double) k;
+                                return k;
                             }
                         }
                         if (l == 35) { /* u > pp[35] */
@@ -149,7 +147,7 @@ public final class RPois implements RandFunction1_Double {
                         pp[k] = q;
                         if (u <= q) {
                             l = k;
-                            return (double) k;
+                            return k;
                         }
                     }
                     l = 35;
@@ -193,8 +191,8 @@ public final class RPois implements RandFunction1_Double {
              * discrete normal probabilities fk.
              */
 
-            b1 = one_24 / mu;
-            b2 = 0.3 * b1 * b1;
+            double b1 = one_24 / mu;
+            double b2 = 0.3 * b1 * b1;
             c3 = one_7 * b1 * b2;
             c2 = b2 - 15. * c3;
             c1 = b1 - 6. * b2 + 45. * c3;
@@ -275,7 +273,7 @@ public final class RPois implements RandFunction1_Double {
     }
 
     @Override
-    public double evaluate(double mu, RandomNumberProvider rand) {
+    public double execute(double mu, RandomNumberProvider rand) {
         return rpois(mu, rand);
     }
 }
diff --git a/com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/stats/RWeibull.java b/com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/stats/RWeibull.java
index 3686f96591d283d05747f0a49deb6dbb5b4c1b93..78d9e38318d59cea2ea982a18ea98f573fa1376d 100644
--- a/com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/stats/RWeibull.java
+++ b/com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/stats/RWeibull.java
@@ -14,11 +14,11 @@ package com.oracle.truffle.r.library.stats;
 import com.oracle.truffle.r.library.stats.RandGenerationFunctions.RandFunction2_Double;
 import com.oracle.truffle.r.library.stats.RandGenerationFunctions.RandomNumberProvider;
 
-public final class RWeibull implements RandFunction2_Double {
+public final class RWeibull extends RandFunction2_Double {
     @Override
-    public double evaluate(double shape, double scale, RandomNumberProvider rand) {
+    public double execute(double shape, double scale, RandomNumberProvider rand) {
         if (!Double.isFinite(shape) || !Double.isFinite(scale) || shape <= 0. || scale <= 0.) {
-            return scale == 0. ? 0. : RMath.mlError();
+            return scale == 0. ? 0. : RMathError.defaultError();
         }
 
         return scale * Math.pow(-Math.log(rand.unifRand()), 1.0 / shape);
diff --git a/com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/stats/RandGenerationFunctions.java b/com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/stats/RandGenerationFunctions.java
index b3548e5ea37864b9ef8641ae6a6b5d13ac0b7e56..61aae8184e43a191d9c6f38f7941902da30f50dd 100644
--- a/com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/stats/RandGenerationFunctions.java
+++ b/com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/stats/RandGenerationFunctions.java
@@ -22,16 +22,21 @@ import java.util.Arrays;
 import com.oracle.truffle.api.CompilerDirectives.CompilationFinal;
 import com.oracle.truffle.api.dsl.Cached;
 import com.oracle.truffle.api.dsl.Specialization;
+import com.oracle.truffle.api.dsl.TypeSystemReference;
 import com.oracle.truffle.api.nodes.Node;
 import com.oracle.truffle.api.profiles.BranchProfile;
 import com.oracle.truffle.api.profiles.LoopConditionProfile;
-import com.oracle.truffle.api.profiles.ValueProfile;
 import com.oracle.truffle.r.library.stats.RandGenerationFunctionsFactory.ConvertToLengthNodeGen;
+import com.oracle.truffle.r.library.stats.RandGenerationFunctionsFactory.RandFunction1NodeGen;
+import com.oracle.truffle.r.library.stats.RandGenerationFunctionsFactory.RandFunction2NodeGen;
+import com.oracle.truffle.r.library.stats.RandGenerationFunctionsFactory.RandFunction3NodeGen;
+import com.oracle.truffle.r.nodes.EmptyTypeSystemFlatLayout;
 import com.oracle.truffle.r.nodes.builtin.CastBuilder;
 import com.oracle.truffle.r.nodes.builtin.RExternalBuiltinNode;
 import com.oracle.truffle.r.nodes.profile.VectorLengthProfile;
 import com.oracle.truffle.r.nodes.unary.CastIntegerNode;
 import com.oracle.truffle.r.runtime.RError;
+import com.oracle.truffle.r.runtime.RInternalError;
 import com.oracle.truffle.r.runtime.RRuntime;
 import com.oracle.truffle.r.runtime.data.RDataFactory;
 import com.oracle.truffle.r.runtime.data.RDouble;
@@ -43,6 +48,11 @@ import com.oracle.truffle.r.runtime.rng.RRNG;
 import com.oracle.truffle.r.runtime.rng.RRNG.NormKind;
 import com.oracle.truffle.r.runtime.rng.RandomNumberGenerator;
 
+/**
+ * Contains infrastructure for R external functions implementing generation of a random value from
+ * given random value distribution. To implement such external function, implement one of:
+ * {@link RandFunction3_Double}, {@link RandFunction2_Double} or {@link RandFunction1_Double}.
+ */
 public final class RandGenerationFunctions {
     @CompilationFinal private static final RDouble DUMMY_VECTOR = RDouble.valueOf(1);
 
@@ -51,14 +61,22 @@ public final class RandGenerationFunctions {
     }
 
     public static final class RandomNumberProvider {
-        private final RandomNumberGenerator generator;
-        private final NormKind normKind;
+        final RandomNumberGenerator generator;
+        final NormKind normKind;
 
         public RandomNumberProvider(RandomNumberGenerator generator, NormKind normKind) {
             this.generator = generator;
             this.normKind = normKind;
         }
 
+        public static RandomNumberProvider fromCurrentRNG() {
+            return new RandomNumberProvider(RRNG.currentGenerator(), RRNG.currentNormKind());
+        }
+
+        protected boolean isSame(RandomNumberProvider other) {
+            return this.generator == other.generator && this.normKind == other.normKind;
+        }
+
         public double unifRand() {
             return generator.genrandDouble();
         }
@@ -74,135 +92,32 @@ public final class RandGenerationFunctions {
 
     // inspired by the DEFRAND{X}_REAL and DEFRAND{X}_INT macros in GnuR
 
-    public interface RandFunction3_Double {
-        double evaluate(double a, double b, double c, RandomNumberProvider rand);
+    public abstract static class RandFunction3_Double extends Node {
+        public abstract double execute(double a, double b, double c, RandomNumberProvider rand);
     }
 
-    public interface RandFunction2_Double extends RandFunction3_Double {
-        double evaluate(double a, double b, RandomNumberProvider rand);
+    public abstract static class RandFunction2_Double extends RandFunction3_Double {
+        public abstract double execute(double a, double b, RandomNumberProvider rand);
 
         @Override
-        default double evaluate(double a, double b, double c, RandomNumberProvider rand) {
-            return evaluate(a, b, rand);
+        public final double execute(double a, double b, double c, RandomNumberProvider rand) {
+            return execute(a, b, rand);
         }
     }
 
-    public interface RandFunction1_Double extends RandFunction2_Double {
-        double evaluate(double a, RandomNumberProvider rand);
+    public abstract static class RandFunction1_Double extends RandFunction2_Double {
+        public abstract double execute(double a, RandomNumberProvider rand);
 
         @Override
-        default double evaluate(double a, double b, RandomNumberProvider rand) {
-            return evaluate(a, rand);
-        }
-    }
-
-    static final class RandGenerationProfiles {
-        final BranchProfile nanResult = BranchProfile.create();
-        final BranchProfile nan = BranchProfile.create();
-        final VectorLengthProfile resultVectorLengthProfile = VectorLengthProfile.create();
-        final LoopConditionProfile loopConditionProfile = LoopConditionProfile.createCountingProfile();
-        private final ValueProfile randClassProfile = ValueProfile.createClassProfile();
-        private final ValueProfile generatorProfile = ValueProfile.createIdentityProfile();
-        private final ValueProfile normKindProfile = ValueProfile.createEqualityProfile();
-
-        public static RandGenerationProfiles create() {
-            return new RandGenerationProfiles();
-        }
-
-        public RandomNumberProvider createRandProvider() {
-            return new RandomNumberProvider(randClassProfile.profile(generatorProfile.profile(RRNG.currentGenerator())), normKindProfile.profile(RRNG.currentNormKind()));
-        }
-    }
-
-    private static RAbstractIntVector evaluate3Int(Node node, RandFunction3_Double function, int lengthIn, RAbstractDoubleVector a, RAbstractDoubleVector b, RAbstractDoubleVector c,
-                    RandGenerationProfiles profiles) {
-        int length = lengthIn;
-        int aLength = a.getLength();
-        int bLength = b.getLength();
-        int cLength = c.getLength();
-        if (aLength == 0 || bLength == 0 || cLength == 0) {
-            profiles.nanResult.enter();
-            RError.warning(SHOW_CALLER, RError.Message.NA_PRODUCED);
-            int[] nansResult = new int[length];
-            Arrays.fill(nansResult, RRuntime.INT_NA);
-            return RDataFactory.createIntVector(nansResult, false);
-        }
-
-        length = profiles.resultVectorLengthProfile.profile(length);
-        RNode.reportWork(node, length);
-        boolean nans = false;
-        int[] result = new int[length];
-        RRNG.getRNGState();
-        RandomNumberProvider rand = profiles.createRandProvider();
-        profiles.loopConditionProfile.profileCounted(length);
-        for (int i = 0; profiles.loopConditionProfile.inject(i < length); i++) {
-            double aValue = a.getDataAt(i % aLength);
-            double bValue = b.getDataAt(i % bLength);
-            double cValue = c.getDataAt(i % cLength);
-            double value = function.evaluate(aValue, bValue, cValue, rand);
-            if (Double.isNaN(value) || value < Integer.MIN_VALUE || value > Integer.MAX_VALUE) {
-                profiles.nan.enter();
-                nans = true;
-                result[i] = RRuntime.INT_NA;
-            } else {
-                result[i] = (int) value;
-            }
-        }
-        RRNG.putRNGState();
-        if (nans) {
-            RError.warning(SHOW_CALLER, RError.Message.NA_PRODUCED);
-        }
-        return RDataFactory.createIntVector(result, !nans);
-    }
-
-    private static RAbstractDoubleVector evaluate3Double(Node node, RandFunction3_Double function, int lengthIn, RAbstractDoubleVector a, RAbstractDoubleVector b, RAbstractDoubleVector c,
-                    RandGenerationProfiles profiles) {
-        int length = lengthIn;
-        int aLength = a.getLength();
-        int bLength = b.getLength();
-        int cLength = c.getLength();
-        if (aLength == 0 || bLength == 0 || cLength == 0) {
-            profiles.nanResult.enter();
-            RError.warning(SHOW_CALLER, RError.Message.NA_PRODUCED);
-            return createVectorOf(length, RRuntime.DOUBLE_NA);
-        }
-
-        length = profiles.resultVectorLengthProfile.profile(length);
-        RNode.reportWork(node, length);
-        boolean nans = false;
-        double[] result;
-        result = new double[length];
-        RRNG.getRNGState();
-        RandomNumberProvider rand = profiles.createRandProvider();
-        profiles.loopConditionProfile.profileCounted(length);
-        for (int i = 0; profiles.loopConditionProfile.inject(i < length); i++) {
-            double aValue = a.getDataAt(i % aLength);
-            double bValue = b.getDataAt(i % bLength);
-            double cValue = c.getDataAt(i % cLength);
-            double value = function.evaluate(aValue, bValue, cValue, rand);
-            if (Double.isNaN(value) || RRuntime.isNA(value)) {
-                profiles.nan.enter();
-                nans = true;
-            }
-            result[i] = value;
-        }
-        RRNG.putRNGState();
-        if (nans) {
-            RError.warning(SHOW_CALLER, RError.Message.NA_PRODUCED);
+        public final double execute(double a, double b, RandomNumberProvider rand) {
+            return execute(a, rand);
         }
-        return RDataFactory.createDoubleVector(result, !nans);
-    }
-
-    private static RAbstractDoubleVector createVectorOf(int length, double element) {
-        double[] nansResult = new double[length];
-        Arrays.fill(nansResult, element);
-        return RDataFactory.createDoubleVector(nansResult, false);
     }
 
     /**
      * Converts given value to actual length that should be used as length of the output vector. The
      * argument must be cast using {@link #addLengthCast(CastBuilder)}. Using this node allows us to
-     * avoid casting of long vectors to integers, if we only need to know their length.
+     * avoid casting of long vectors to integers if we only need to know their length.
      */
     protected abstract static class ConvertToLength extends Node {
         public abstract int execute(RAbstractVector value);
@@ -229,112 +144,244 @@ public final class RandGenerationFunctions {
         }
     }
 
-    public abstract static class Function3_IntNode extends RExternalBuiltinNode.Arg4 {
-        private final RandFunction3_Double function;
+    /**
+     * Executor node handles the validation, the loop over all vector elements, the creation of the
+     * result vector, and similar. The random function is provided as implementation of
+     * {@link RandFunction3_Double}.
+     */
+    @TypeSystemReference(EmptyTypeSystemFlatLayout.class)
+    protected abstract static class RandFunctionExecutorBase extends Node {
+        static final class RandGenerationNodeData {
+            final BranchProfile nanResult = BranchProfile.create();
+            final BranchProfile nan = BranchProfile.create();
+            final VectorLengthProfile resultVectorLengthProfile = VectorLengthProfile.create();
+            final LoopConditionProfile loopConditionProfile = LoopConditionProfile.createCountingProfile();
+
+            public static RandGenerationNodeData create() {
+                return new RandGenerationNodeData();
+            }
+        }
+
+        public abstract Object execute(RAbstractVector length, RAbstractDoubleVector a, RAbstractDoubleVector b, RAbstractDoubleVector c, RandomNumberProvider rand);
+
         @Child private ConvertToLength convertToLength = ConvertToLengthNodeGen.create();
 
-        protected Function3_IntNode(RandFunction3_Double function) {
-            this.function = function;
+        @Specialization(guards = {"randCached.isSame(rand)"})
+        protected final Object evaluateWithCached(RAbstractVector lengthVec, RAbstractDoubleVector a, RAbstractDoubleVector b, RAbstractDoubleVector c,
+                        @SuppressWarnings("unused") RandomNumberProvider rand,
+                        @Cached("rand") RandomNumberProvider randCached,
+                        @Cached("create()") RandGenerationNodeData nodeData) {
+            return evaluateWrapper(lengthVec, a, b, c, randCached, nodeData);
         }
 
-        @Override
-        protected void createCasts(CastBuilder casts) {
-            ConvertToLength.addLengthCast(casts);
-            casts.arg(1).asDoubleVector();
-            casts.arg(2).asDoubleVector();
-            casts.arg(3).asDoubleVector();
+        @Specialization(contains = "evaluateWithCached")
+        protected final Object evaluateFallback(RAbstractVector lengthVec, RAbstractDoubleVector a, RAbstractDoubleVector b, RAbstractDoubleVector c, RandomNumberProvider rand,
+                        @Cached("create()") RandGenerationNodeData nodeData) {
+            return evaluateWrapper(lengthVec, a, b, c, rand, nodeData);
         }
 
-        @Specialization
-        protected RAbstractIntVector evaluate(RAbstractVector length, RAbstractDoubleVector a, RAbstractDoubleVector b, RAbstractDoubleVector c,
-                        @Cached("create()") RandGenerationProfiles profiles) {
-            return evaluate3Int(this, function, convertToLength.execute(length), a, b, c, profiles);
+        private Object evaluateWrapper(RAbstractVector lengthVec, RAbstractDoubleVector a, RAbstractDoubleVector b, RAbstractDoubleVector c, RandomNumberProvider rand,
+                        RandGenerationNodeData nodeData) {
+            int length = nodeData.resultVectorLengthProfile.profile(convertToLength.execute(lengthVec));
+            RNode.reportWork(this, length);
+            return evaluate(length, a, b, c, nodeData, rand);
+        }
+
+        @SuppressWarnings("unused")
+        Object evaluate(int length, RAbstractDoubleVector a, RAbstractDoubleVector b, RAbstractDoubleVector c, RandGenerationNodeData nodeData, RandomNumberProvider randProvider) {
+            // DSL generates code for this class too, with abstract method it would not compile
+            throw RInternalError.shouldNotReachHere("must be overridden");
+        }
+
+        static void putRNGState() {
+            // Note: we call putRNGState only if we actually changed the state, i.e. called random
+            // number generation. We do not need to getRNGState() because the parent wrapper node
+            // should do that for us
+            RRNG.putRNGState();
+        }
+
+        static void showNAWarning() {
+            RError.warning(SHOW_CALLER, RError.Message.NA_PRODUCED);
         }
     }
 
-    public abstract static class Function2_IntNode extends RExternalBuiltinNode.Arg3 {
-        private final RandFunction2_Double function;
-        @Child private ConvertToLength convertToLength = ConvertToLengthNodeGen.create();
+    @TypeSystemReference(EmptyTypeSystemFlatLayout.class)
+    protected abstract static class RandFunctionIntExecutorNode extends RandFunctionExecutorBase {
+        @Child private RandFunction3_Double function;
 
-        protected Function2_IntNode(RandFunction2_Double function) {
+        protected RandFunctionIntExecutorNode(RandFunction3_Double function) {
             this.function = function;
         }
 
         @Override
-        protected void createCasts(CastBuilder casts) {
-            ConvertToLength.addLengthCast(casts);
-            casts.arg(1).asDoubleVector();
-            casts.arg(2).asDoubleVector();
-        }
+        protected RAbstractIntVector evaluate(int length, RAbstractDoubleVector a, RAbstractDoubleVector b, RAbstractDoubleVector c, RandGenerationNodeData nodeData,
+                        RandomNumberProvider randProvider) {
+            int aLength = a.getLength();
+            int bLength = b.getLength();
+            int cLength = c.getLength();
+            if (aLength == 0 || bLength == 0 || cLength == 0) {
+                nodeData.nanResult.enter();
+                showNAWarning();
+                int[] nansResult = new int[length];
+                Arrays.fill(nansResult, RRuntime.INT_NA);
+                return RDataFactory.createIntVector(nansResult, false);
+            }
 
-        @Specialization
-        protected RAbstractIntVector evaluate(RAbstractVector length, RAbstractDoubleVector a, RAbstractDoubleVector b,
-                        @Cached("create()") RandGenerationProfiles profiles) {
-            return evaluate3Int(this, function, convertToLength.execute(length), a, b, DUMMY_VECTOR, profiles);
+            boolean nans = false;
+            int[] result = new int[length];
+            nodeData.loopConditionProfile.profileCounted(length);
+            for (int i = 0; nodeData.loopConditionProfile.inject(i < length); i++) {
+                double aValue = a.getDataAt(i % aLength);
+                double bValue = b.getDataAt(i % bLength);
+                double cValue = c.getDataAt(i % cLength);
+                double value = function.execute(aValue, bValue, cValue, randProvider);
+                if (Double.isNaN(value) || value < Integer.MIN_VALUE || value > Integer.MAX_VALUE) {
+                    nodeData.nan.enter();
+                    nans = true;
+                    result[i] = RRuntime.INT_NA;
+                } else {
+                    result[i] = (int) value;
+                }
+            }
+            putRNGState();
+            if (nans) {
+                showNAWarning();
+            }
+            return RDataFactory.createIntVector(result, !nans);
         }
     }
 
-    public abstract static class Function1_IntNode extends RExternalBuiltinNode.Arg2 {
-        private final RandFunction1_Double function;
-        @Child private ConvertToLength convertToLength = ConvertToLengthNodeGen.create();
+    @TypeSystemReference(EmptyTypeSystemFlatLayout.class)
+    protected abstract static class RandFunctionDoubleExecutorNode extends RandFunctionExecutorBase {
+        @Child private RandFunction3_Double function;
 
-        protected Function1_IntNode(RandFunction1_Double function) {
+        protected RandFunctionDoubleExecutorNode(RandFunction3_Double function) {
             this.function = function;
         }
 
         @Override
-        protected void createCasts(CastBuilder casts) {
+        protected RAbstractDoubleVector evaluate(int length, RAbstractDoubleVector a, RAbstractDoubleVector b, RAbstractDoubleVector c, RandGenerationNodeData nodeData,
+                        RandomNumberProvider randProvider) {
+            int aLength = a.getLength();
+            int bLength = b.getLength();
+            int cLength = c.getLength();
+            if (aLength == 0 || bLength == 0 || cLength == 0) {
+                nodeData.nanResult.enter();
+                showNAWarning();
+                double[] nansResult = new double[length];
+                Arrays.fill(nansResult, RRuntime.DOUBLE_NA);
+                return RDataFactory.createDoubleVector(nansResult, false);
+            }
+
+            boolean nans = false;
+            double[] result;
+            result = new double[length];
+            nodeData.loopConditionProfile.profileCounted(length);
+            for (int i = 0; nodeData.loopConditionProfile.inject(i < length); i++) {
+                double aValue = a.getDataAt(i % aLength);
+                double bValue = b.getDataAt(i % bLength);
+                double cValue = c.getDataAt(i % cLength);
+                double value = function.execute(aValue, bValue, cValue, randProvider);
+                if (Double.isNaN(value) || RRuntime.isNA(value)) {
+                    nodeData.nan.enter();
+                    nans = true;
+                }
+                result[i] = value;
+            }
+            putRNGState();
+            if (nans) {
+                showNAWarning();
+            }
+            return RDataFactory.createDoubleVector(result, !nans);
+        }
+    }
+
+    public abstract static class RandFunction3Node extends RExternalBuiltinNode.Arg4 {
+        @Child private RandFunctionExecutorBase inner;
+
+        protected RandFunction3Node(RandFunctionExecutorBase inner) {
+            this.inner = inner;
+        }
+
+        public static RandFunction3Node createInt(RandFunction3_Double function) {
+            return RandFunction3NodeGen.create(RandGenerationFunctionsFactory.RandFunctionIntExecutorNodeGen.create(function));
+        }
+
+        // Note: for completeness of the API
+        @SuppressWarnings("unused")
+        public static RandFunction3Node createDouble(RandFunction3_Double function) {
+            return RandFunction3NodeGen.create(RandGenerationFunctionsFactory.RandFunctionDoubleExecutorNodeGen.create(function));
+        }
+
+        @Override
+        protected final void createCasts(CastBuilder casts) {
             ConvertToLength.addLengthCast(casts);
             casts.arg(1).asDoubleVector();
+            casts.arg(2).asDoubleVector();
+            casts.arg(3).asDoubleVector();
         }
 
         @Specialization
-        protected RAbstractIntVector evaluate(RAbstractVector length, RAbstractDoubleVector a,
-                        @Cached("create()") RandGenerationProfiles profiles) {
-            return evaluate3Int(this, function, convertToLength.execute(length), a, DUMMY_VECTOR, DUMMY_VECTOR, profiles);
+        protected Object evaluate(RAbstractVector length, RAbstractDoubleVector a, RAbstractDoubleVector b, RAbstractDoubleVector c) {
+            RRNG.getRNGState();
+            return inner.execute(length, a, b, c, RandomNumberProvider.fromCurrentRNG());
         }
     }
 
-    public abstract static class Function1_DoubleNode extends RExternalBuiltinNode.Arg2 {
-        private final RandFunction1_Double function;
-        @Child private ConvertToLength convertToLength = ConvertToLengthNodeGen.create();
+    public abstract static class RandFunction2Node extends RExternalBuiltinNode.Arg3 {
+        @Child private RandFunctionExecutorBase inner;
 
-        protected Function1_DoubleNode(RandFunction1_Double function) {
-            this.function = function;
+        protected RandFunction2Node(RandFunctionExecutorBase inner) {
+            this.inner = inner;
+        }
+
+        public static RandFunction2Node createInt(RandFunction2_Double function) {
+            return RandFunction2NodeGen.create(RandGenerationFunctionsFactory.RandFunctionIntExecutorNodeGen.create(function));
+        }
+
+        public static RandFunction2Node createDouble(RandFunction2_Double function) {
+            return RandFunction2NodeGen.create(RandGenerationFunctionsFactory.RandFunctionDoubleExecutorNodeGen.create(function));
         }
 
         @Override
-        protected void createCasts(CastBuilder casts) {
+        protected final void createCasts(CastBuilder casts) {
             ConvertToLength.addLengthCast(casts);
             casts.arg(1).asDoubleVector();
+            casts.arg(2).asDoubleVector();
         }
 
         @Specialization
-        protected RAbstractDoubleVector evaluate(RAbstractVector length, RAbstractDoubleVector a,
-                        @Cached("create()") RandGenerationProfiles profiles) {
-            return evaluate3Double(this, function, convertToLength.execute(length), a, DUMMY_VECTOR, DUMMY_VECTOR, profiles);
+        protected Object evaluate(RAbstractVector length, RAbstractDoubleVector a, RAbstractDoubleVector b) {
+            RRNG.getRNGState();
+            return inner.execute(length, a, b, DUMMY_VECTOR, RandomNumberProvider.fromCurrentRNG());
         }
     }
 
-    public abstract static class Function2_DoubleNode extends RExternalBuiltinNode.Arg3 {
-        private final RandFunction2_Double function;
-        @Child private ConvertToLength convertToLength = ConvertToLengthNodeGen.create();
+    public abstract static class RandFunction1Node extends RExternalBuiltinNode.Arg2 {
+        @Child private RandFunctionExecutorBase inner;
 
-        protected Function2_DoubleNode(RandFunction2_Double function) {
-            this.function = function;
+        protected RandFunction1Node(RandFunctionExecutorBase inner) {
+            this.inner = inner;
+        }
+
+        public static RandFunction1Node createInt(RandFunction1_Double function) {
+            return RandFunction1NodeGen.create(RandGenerationFunctionsFactory.RandFunctionIntExecutorNodeGen.create(function));
+        }
+
+        public static RandFunction1Node createDouble(RandFunction1_Double function) {
+            return RandFunction1NodeGen.create(RandGenerationFunctionsFactory.RandFunctionDoubleExecutorNodeGen.create(function));
         }
 
         @Override
-        protected void createCasts(CastBuilder casts) {
+        protected final void createCasts(CastBuilder casts) {
             ConvertToLength.addLengthCast(casts);
             casts.arg(1).asDoubleVector();
-            casts.arg(2).asDoubleVector();
         }
 
         @Specialization
-        protected RAbstractDoubleVector evaluate(RAbstractVector length, RAbstractDoubleVector a, RAbstractDoubleVector b,
-                        @Cached("create()") RandGenerationProfiles profiles) {
-            return evaluate3Double(this, function, convertToLength.execute(length), a, b, DUMMY_VECTOR, profiles);
+        protected Object evaluate(RAbstractVector length, RAbstractDoubleVector a) {
+            RRNG.getRNGState();
+            return inner.execute(length, a, DUMMY_VECTOR, DUMMY_VECTOR, RandomNumberProvider.fromCurrentRNG());
         }
     }
 }
diff --git a/com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/stats/Random2.java b/com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/stats/Random2.java
index 729f0d0833ed777de42e12fc552206ce7d12f58d..de77422aefb34b79d6788ebc94672fe500c0c1be 100644
--- a/com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/stats/Random2.java
+++ b/com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/stats/Random2.java
@@ -17,7 +17,10 @@ import static com.oracle.truffle.r.library.stats.DPQ.rdtqiv;
 /*
  * Logic derived from GNU-R, see inline comments.
  */
-public class Random2 {
+public final class Random2 {
+    private Random2() {
+        // only static members
+    }
 
     // from GNUR: qnorm.c
     public static double qnorm5(double p, double mu, double sigma, boolean lowerTail, boolean logP) {
diff --git a/com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/stats/Rbinom.java b/com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/stats/Rbinom.java
index db6545e1e193ce0332d1ef64f35802b55ab55aa2..4f9080aae6e2193cc0313879512fbe35dcdd331c 100644
--- a/com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/stats/Rbinom.java
+++ b/com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/stats/Rbinom.java
@@ -18,19 +18,22 @@ import com.oracle.truffle.r.runtime.RRuntime;
 
 // transcribed from rbinom.c
 
-public final class Rbinom implements RandFunction2_Double {
+public final class Rbinom extends RandFunction2_Double {
 
     private final Qbinom qbinom = new Qbinom();
 
+    // TODO: some of the variables below are static in GnuR, because they cache intermediate results
+    // that depend on paremeters that often do not change between calls.
+
     @Override
-    public double evaluate(double nin, double pp, RandomNumberProvider rand) {
+    public double execute(double nin, double pp, RandomNumberProvider rand) {
         double psave = -1.0;
         int nsave = -1;
 
         if (!Double.isFinite(nin)) {
             return RRuntime.INT_NA;
         }
-        double r = MathConstants.forceint(nin);
+        double r = RMath.forceint(nin);
         if (r != nin) {
             return RRuntime.INT_NA;
         }
diff --git a/com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/stats/Rf.java b/com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/stats/Rf.java
index 21cbb6d2bcf8609018f0fa730b73c6f59f0c8892..0c1643b0244f60259de6106d60cd0ab1056d01ed 100644
--- a/com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/stats/Rf.java
+++ b/com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/stats/Rf.java
@@ -14,17 +14,17 @@ package com.oracle.truffle.r.library.stats;
 import com.oracle.truffle.r.library.stats.RandGenerationFunctions.RandFunction2_Double;
 import com.oracle.truffle.r.library.stats.RandGenerationFunctions.RandomNumberProvider;
 
-public final class Rf implements RandFunction2_Double {
+public final class Rf extends RandFunction2_Double {
     @Override
-    public double evaluate(double n1, double n2, RandomNumberProvider rand) {
+    public double execute(double n1, double n2, RandomNumberProvider rand) {
         if (Double.isNaN(n1) || Double.isNaN(n2) || n1 <= 0. || n2 <= 0.) {
-            return RMath.mlError();
+            return RMathError.defaultError();
         }
 
         double v1;
         double v2;
-        v1 = Double.isFinite(n1) ? (RChisq.rchisq(n1, rand) / n1) : 1;
-        v2 = Double.isFinite(n2) ? (RChisq.rchisq(n2, rand) / n2) : 1;
+        v1 = Double.isFinite(n1) ? (Chisq.RChisq.rchisq(n1, rand) / n1) : 1;
+        v2 = Double.isFinite(n2) ? (Chisq.RChisq.rchisq(n2, rand) / n2) : 1;
         return v1 / v2;
     }
 }
diff --git a/com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/stats/Rnorm.java b/com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/stats/Rnorm.java
index 1996274e87ea2c9c733dfdf4ad7ff06cb2eb0270..5cdb828e5849d72ec08c661d5e4755a7965294e7 100644
--- a/com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/stats/Rnorm.java
+++ b/com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/stats/Rnorm.java
@@ -11,16 +11,27 @@
  */
 package com.oracle.truffle.r.library.stats;
 
+import com.oracle.truffle.api.profiles.BranchProfile;
+import com.oracle.truffle.api.profiles.ConditionProfile;
+import com.oracle.truffle.api.profiles.ValueProfile;
 import com.oracle.truffle.r.library.stats.RandGenerationFunctions.RandFunction2_Double;
 import com.oracle.truffle.r.library.stats.RandGenerationFunctions.RandomNumberProvider;
 
-public final class Rnorm implements RandFunction2_Double {
+public final class Rnorm extends RandFunction2_Double {
+    private final BranchProfile errorProfile = BranchProfile.create();
+    private final ConditionProfile zeroSigmaProfile = ConditionProfile.createBinaryProfile();
+    private final ValueProfile sigmaValueProfile = ValueProfile.createEqualityProfile();
+    private final ValueProfile muValueProfile = ValueProfile.createEqualityProfile();
+
     @Override
-    public double evaluate(double mu, double sigma, RandomNumberProvider rand) {
+    public double execute(double muIn, double sigmaIn, RandomNumberProvider rand) {
+        double sigma = sigmaValueProfile.profile(sigmaIn);
+        double mu = muValueProfile.profile(muIn);
         if (Double.isNaN(mu) || !Double.isFinite(sigma) || sigma < 0.) {
-            return RMath.mlError();
+            errorProfile.enter();
+            return RMathError.defaultError();
         }
-        if (sigma == 0. || !Double.isFinite(mu)) {
+        if (zeroSigmaProfile.profile(sigma == 0. || !Double.isFinite(mu))) {
             return mu; /* includes mu = +/- Inf with finite sigma */
         } else {
             return mu + sigma * rand.normRand();
diff --git a/com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/stats/Rt.java b/com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/stats/Rt.java
index 51a266499e2e0af2b8c120ff15edcc26ae123310..3804a509615dbb609969e00f40a82cc5f19d9ddc 100644
--- a/com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/stats/Rt.java
+++ b/com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/stats/Rt.java
@@ -11,16 +11,16 @@
  */
 package com.oracle.truffle.r.library.stats;
 
-import static com.oracle.truffle.r.library.stats.RChisq.rchisq;
+import static com.oracle.truffle.r.library.stats.Chisq.RChisq.rchisq;
 
 import com.oracle.truffle.r.library.stats.RandGenerationFunctions.RandFunction1_Double;
 import com.oracle.truffle.r.library.stats.RandGenerationFunctions.RandomNumberProvider;
 
-public final class Rt implements RandFunction1_Double {
+public final class Rt extends RandFunction1_Double {
     @Override
-    public double evaluate(double df, RandomNumberProvider rand) {
+    public double execute(double df, RandomNumberProvider rand) {
         if (Double.isNaN(df) || df <= 0.0) {
-            return RMath.mlError();
+            return RMathError.defaultError();
         }
 
         if (!Double.isFinite(df)) {
diff --git a/com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/stats/Signrank.java b/com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/stats/Signrank.java
index 1b33cb4ddb8d4aeac8960ed8a69100feefeec1e2..662ca852559619924ca46e1f35232f451d3089b0 100644
--- a/com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/stats/Signrank.java
+++ b/com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/stats/Signrank.java
@@ -11,40 +11,39 @@
 
 package com.oracle.truffle.r.library.stats;
 
-import static com.oracle.truffle.r.library.stats.MathConstants.forceint;
+import static com.oracle.truffle.r.library.stats.RMath.forceint;
 
 import com.oracle.truffle.r.library.stats.RandGenerationFunctions.RandFunction1_Double;
 import com.oracle.truffle.r.library.stats.RandGenerationFunctions.RandomNumberProvider;
 
 public final class Signrank {
+    private Signrank() {
+        // only static members
+    }
 
-    public static final class RSignrank implements RandFunction1_Double {
+    public static final class RSignrank extends RandFunction1_Double {
         @Override
-        public double evaluate(double n, RandomNumberProvider rand) {
-            int i;
-            int k;
-            double r;
-
-            if (Double.isNaN(n)) {
-                return n;
+        public double execute(double nIn, RandomNumberProvider rand) {
+            if (Double.isNaN(nIn)) {
+                return nIn;
             }
-            if (Double.isInfinite(n)) {
+            if (Double.isInfinite(nIn)) {
                 // In GnuR these "results" seem to be generated due to the behaviour of R_forceint,
                 // and the "(int) n" cast, which ends up casting +/-infinity to integer...
-                return n < 0 ? RMath.mlError() : 0;
+                return nIn < 0 ? RMathError.defaultError() : 0;
             }
 
-            n = forceint(n);
+            double n = forceint(nIn);
             if (n < 0) {
-                return RMath.mlError();
+                return RMathError.defaultError();
             }
 
             if (n == 0) {
                 return 0;
             }
-            r = 0.0;
-            k = (int) n;
-            for (i = 0; i < k; i++) {
+            double r = 0.0;
+            int k = (int) n;
+            for (int i = 0; i < k; i++) {
                 r += (i + 1) * Math.floor(rand.unifRand() + 0.5);
             }
             return r;
diff --git a/com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/stats/StatsFunctions.java b/com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/stats/StatsFunctions.java
index 48c80044ba8a6b2d181a9f1e1b15564d5e66b66b..9d5484b7634f081ae94fb25cfd6e6d03b15decfd 100644
--- a/com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/stats/StatsFunctions.java
+++ b/com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/stats/StatsFunctions.java
@@ -21,6 +21,8 @@ import com.oracle.truffle.api.nodes.Node;
 import com.oracle.truffle.api.profiles.BranchProfile;
 import com.oracle.truffle.api.profiles.ConditionProfile;
 import com.oracle.truffle.api.profiles.LoopConditionProfile;
+import com.oracle.truffle.r.library.stats.StatsFunctionsFactory.Function4_1NodeGen;
+import com.oracle.truffle.r.library.stats.StatsFunctionsFactory.Function4_2NodeGen;
 import com.oracle.truffle.r.nodes.attributes.UnaryCopyAttributesNode;
 import com.oracle.truffle.r.nodes.builtin.CastBuilder;
 import com.oracle.truffle.r.nodes.builtin.RExternalBuiltinNode;
@@ -44,7 +46,25 @@ public final class StatsFunctions {
         // private
     }
 
-    public interface Function3_2 {
+    public interface Function4_2 {
+        double evaluate(double a, double b, double c, double d, boolean x, boolean y);
+    }
+
+    public interface Function4_1 extends Function4_2 {
+        @Override
+        default double evaluate(double a, double b, double c, double d, boolean x, boolean y) {
+            return evaluate(a, b, c, d, x);
+        }
+
+        double evaluate(double a, double b, double c, double d, boolean x);
+    }
+
+    public interface Function3_2 extends Function4_2 {
+        @Override
+        default double evaluate(double a, double b, double c, double d, boolean x, boolean y) {
+            return evaluate(a, b, c, x, y);
+        }
+
         double evaluate(double a, double b, double c, boolean x, boolean y);
     }
 
@@ -80,9 +100,11 @@ public final class StatsFunctions {
         final NACheck aCheck = NACheck.create();
         final NACheck bCheck = NACheck.create();
         final NACheck cCheck = NACheck.create();
+        final NACheck dCheck = NACheck.create();
         final ConditionProfile copyAttrsFromA = ConditionProfile.createBinaryProfile();
         final ConditionProfile copyAttrsFromB = ConditionProfile.createBinaryProfile();
         final ConditionProfile copyAttrsFromC = ConditionProfile.createBinaryProfile();
+        final ConditionProfile copyAttrsFromD = ConditionProfile.createBinaryProfile();
         final VectorLengthProfile resultVectorLengthProfile = VectorLengthProfile.create();
         final LoopConditionProfile loopConditionProfile = LoopConditionProfile.createCountingProfile();
 
@@ -91,15 +113,16 @@ public final class StatsFunctions {
         }
     }
 
-    private static RAbstractDoubleVector evaluate3(Node node, Function3_2 function, RAbstractDoubleVector a, RAbstractDoubleVector b, RAbstractDoubleVector c, boolean x, boolean y,
-                    StatFunctionProfiles profiles, UnaryCopyAttributesNode copyAttributesNode) {
+    private static RAbstractDoubleVector evaluate4(Node node, Function4_2 function, RAbstractDoubleVector a, RAbstractDoubleVector b, RAbstractDoubleVector c, RAbstractDoubleVector d, boolean x,
+                    boolean y, StatFunctionProfiles profiles, UnaryCopyAttributesNode copyAttributesNode) {
         int aLength = a.getLength();
         int bLength = b.getLength();
         int cLength = c.getLength();
-        if (aLength == 0 || bLength == 0 || cLength == 0) {
+        int dLength = d.getLength();
+        if (aLength == 0 || bLength == 0 || cLength == 0 || dLength == 0) {
             return RDataFactory.createEmptyDoubleVector();
         }
-        int length = profiles.resultVectorLengthProfile.profile(Math.max(aLength, Math.max(bLength, cLength)));
+        int length = profiles.resultVectorLengthProfile.profile(Math.max(aLength, Math.max(bLength, Math.max(cLength, dLength))));
         RNode.reportWork(node, length);
         double[] result = new double[length];
 
@@ -108,22 +131,24 @@ public final class StatsFunctions {
         profiles.aCheck.enable(a);
         profiles.bCheck.enable(b);
         profiles.cCheck.enable(c);
+        profiles.dCheck.enable(d);
         profiles.loopConditionProfile.profileCounted(length);
         for (int i = 0; profiles.loopConditionProfile.inject(i < length); i++) {
             double aValue = a.getDataAt(i % aLength);
             double bValue = b.getDataAt(i % bLength);
             double cValue = c.getDataAt(i % cLength);
+            double dValue = d.getDataAt(i % dLength);
             double value;
-            if (Double.isNaN(aValue) || Double.isNaN(bValue) || Double.isNaN(cValue)) {
+            if (Double.isNaN(aValue) || Double.isNaN(bValue) || Double.isNaN(cValue) || Double.isNaN(dValue)) {
                 profiles.nan.enter();
-                if (profiles.aCheck.check(aValue) || profiles.bCheck.check(bValue) || profiles.cCheck.check(cValue)) {
+                if (profiles.aCheck.check(aValue) || profiles.bCheck.check(bValue) || profiles.cCheck.check(cValue) || profiles.cCheck.check(dValue)) {
                     value = RRuntime.DOUBLE_NA;
                     complete = false;
                 } else {
                     value = Double.NaN;
                 }
             } else {
-                value = function.evaluate(aValue, bValue, cValue, x, y);
+                value = function.evaluate(aValue, bValue, cValue, dValue, x, y);
                 if (Double.isNaN(value)) {
                     profiles.nan.enter();
                     nans = true;
@@ -143,6 +168,8 @@ public final class StatsFunctions {
             copyAttributesNode.execute(resultVec, b);
         } else if (profiles.copyAttrsFromC.profile(cLength == length)) {
             copyAttributesNode.execute(resultVec, c);
+        } else if (profiles.copyAttrsFromD.profile((dLength == length))) {
+            copyAttributesNode.execute(resultVec, d);
         }
 
         return resultVec;
@@ -168,7 +195,64 @@ public final class StatsFunctions {
         protected RAbstractDoubleVector evaluate(RAbstractDoubleVector a, RAbstractDoubleVector b, RAbstractDoubleVector c, boolean x, boolean y,
                         @Cached("create()") StatFunctionProfiles profiles,
                         @Cached("create()") UnaryCopyAttributesNode copyAttributesNode) {
-            return evaluate3(this, function, a, b, c, x, y, profiles, copyAttributesNode);
+            return evaluate4(this, function, a, b, c, DUMMY_VECTOR, x, y, profiles, copyAttributesNode);
+        }
+    }
+
+    public abstract static class Function4_1Node extends RExternalBuiltinNode.Arg5 {
+        private final Function4_1 function;
+
+        public Function4_1Node(Function4_1 function) {
+            this.function = function;
+        }
+
+        public static Function4_1Node create(Function4_1 function) {
+            return Function4_1NodeGen.create(function);
+        }
+
+        @Override
+        protected void createCasts(CastBuilder casts) {
+            casts.arg(0).asDoubleVector();
+            casts.arg(1).asDoubleVector();
+            casts.arg(2).asDoubleVector();
+            casts.arg(3).asDoubleVector();
+            casts.arg(4).asLogicalVector().findFirst().map(toBoolean());
+        }
+
+        @Specialization
+        protected RAbstractDoubleVector evaluate(RAbstractDoubleVector a, RAbstractDoubleVector b, RAbstractDoubleVector c, RAbstractDoubleVector d, boolean x,
+                        @Cached("create()") StatFunctionProfiles profiles,
+                        @Cached("create()") UnaryCopyAttributesNode copyAttributesNode) {
+            return evaluate4(this, function, a, b, c, d, x, false /* dummy */, profiles, copyAttributesNode);
+        }
+    }
+
+    public abstract static class Function4_2Node extends RExternalBuiltinNode.Arg6 {
+        private final Function4_2 function;
+
+        public Function4_2Node(Function4_2 function) {
+            this.function = function;
+        }
+
+        public static Function4_2Node create(Function4_2 function) {
+            return Function4_2NodeGen.create(function);
+        }
+
+        @Override
+        protected void createCasts(CastBuilder casts) {
+            casts.arg(0).asDoubleVector();
+            casts.arg(1).asDoubleVector();
+            casts.arg(2).asDoubleVector();
+            casts.arg(3).asDoubleVector();
+            casts.arg(4).asLogicalVector().findFirst().map(toBoolean());
+            casts.arg(5).asLogicalVector().findFirst().map(toBoolean());
+        }
+
+        @Specialization
+        protected RAbstractDoubleVector evaluate(RAbstractDoubleVector a, RAbstractDoubleVector b, RAbstractDoubleVector c, RAbstractDoubleVector d, boolean x, boolean y,
+                        @Cached("create()") StatFunctionProfiles profiles,
+                        @Cached("create()") UnaryCopyAttributesNode copyAttributesNode) {
+            return evaluate4(this, function, a, b, c, d, x, y, profiles, copyAttributesNode);
         }
     }
 
@@ -191,7 +275,7 @@ public final class StatsFunctions {
         protected RAbstractDoubleVector evaluate(RAbstractDoubleVector a, RAbstractDoubleVector b, RAbstractDoubleVector c, boolean x,
                         @Cached("create()") StatFunctionProfiles profiles,
                         @Cached("create()") UnaryCopyAttributesNode copyAttributesNode) {
-            return evaluate3(this, function, a, b, c, x, false /* dummy */, profiles, copyAttributesNode);
+            return evaluate4(this, function, a, b, c, DUMMY_VECTOR, x, false /* dummy */, profiles, copyAttributesNode);
         }
     }
 
@@ -213,7 +297,7 @@ public final class StatsFunctions {
         protected RAbstractDoubleVector evaluate(RAbstractDoubleVector a, RAbstractDoubleVector b, boolean x,
                         @Cached("create()") StatFunctionProfiles profiles,
                         @Cached("create()") UnaryCopyAttributesNode copyAttributesNode) {
-            return evaluate3(this, function, a, b, DUMMY_VECTOR, x, false /* dummy */, profiles, copyAttributesNode);
+            return evaluate4(this, function, a, b, DUMMY_VECTOR, DUMMY_VECTOR, x, false /* dummy */, profiles, copyAttributesNode);
         }
     }
 
@@ -236,7 +320,7 @@ public final class StatsFunctions {
         protected RAbstractDoubleVector evaluate(RAbstractDoubleVector a, RAbstractDoubleVector b, boolean x, boolean y,
                         @Cached("create()") StatFunctionProfiles profiles,
                         @Cached("create()") UnaryCopyAttributesNode copyAttributesNode) {
-            return evaluate3(this, function, a, b, DUMMY_VECTOR, x, y, profiles, copyAttributesNode);
+            return evaluate4(this, function, a, b, DUMMY_VECTOR, DUMMY_VECTOR, x, y, profiles, copyAttributesNode);
         }
     }
 
diff --git a/com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/stats/TOMS708.java b/com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/stats/TOMS708.java
index 65056493bd7f7358f33beff9b9ef16afa8141c67..9f0ee17d7b44b2a40a399ec10a63b0beccd7c870 100644
--- a/com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/stats/TOMS708.java
+++ b/com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/stats/TOMS708.java
@@ -11,7 +11,6 @@
  */
 package com.oracle.truffle.r.library.stats;
 
-import static com.oracle.truffle.r.library.stats.MathConstants.M_LN2;
 import static com.oracle.truffle.r.library.stats.MathConstants.M_LN_SQRT_2PI;
 import static com.oracle.truffle.r.library.stats.MathConstants.M_SQRT_PI;
 import static com.oracle.truffle.r.library.stats.MathConstants.logspaceAdd;
@@ -26,7 +25,10 @@ import com.oracle.truffle.r.runtime.RRuntime;
  * transcribed from toms708.c - as the original file contains no copyright header, we assume that it is copyright R code and R foundation.
  */
 
-public class TOMS708 {
+public final class TOMS708 {
+    private TOMS708() {
+        // only static members
+    }
 
     @SuppressWarnings("unused")
     private static void debugPrintf(String format, Object... args) {
@@ -38,11 +40,6 @@ public class TOMS708 {
         RError.warning(RError.SHOW_CALLER, Message.GENERIC, String.format(format, args));
     }
 
-    // R_Log1_Exp
-    public static double log1Exp(double x) {
-        return ((x) > -M_LN2 ? log(-rexpm1(x)) : log1p(-exp(x)));
-    }
-
     private static double sin(double v) {
         return Math.sin(v);
     }
@@ -59,10 +56,6 @@ public class TOMS708 {
         return Math.sqrt(v);
     }
 
-    private static double log1p(double v) {
-        return Math.log1p(v);
-    }
-
     private static double exp(double v) {
         return Math.exp(v);
     }
@@ -85,22 +78,6 @@ public class TOMS708 {
 
     private static final double ML_NEGINF = Double.NEGATIVE_INFINITY;
     private static final int INT_MAX = Integer.MAX_VALUE;
-    private static final double DBL_MIN = Double.MIN_NORMAL;
-    private static final double INV_SQRT_2_PI = .398942280401433; /* == 1/sqrt(2*pi); */
-
-    public static final class MathException extends RuntimeException {
-        private static final long serialVersionUID = -4745984791703065276L;
-
-        private final int code;
-
-        public MathException(int code) {
-            this.code = code;
-        }
-
-        public int getCode() {
-            return code;
-        }
-    }
 
     public static final class Bratio {
         public double w;
@@ -280,7 +257,7 @@ public class TOMS708 {
 
                                 if (b0 < Math.min(eps, eps * a0)) { /* L80: */
                                     w = fpser(a0, b0, x0, eps, logP);
-                                    w1 = logP ? log1Exp(w) : 0.5 - w + 0.5;
+                                    w1 = logP ? DPQ.rlog1exp(w) : 0.5 - w + 0.5;
                                     debugPrintf("  b0 small -> w := fpser(*) = %.15f\n", w);
                                     break L_end;
                                 }
@@ -357,7 +334,7 @@ public class TOMS708 {
                                         w1 = Double.NEGATIVE_INFINITY; // = 0 on log-scale
                                     }
                                     bgrat.w = w1;
-                                    bgrat.bgrat(b0, a0, y0, x0, 15 * eps, false);
+                                    bgrat.bgrat(b0, a0, y0, x0, 15 * eps, true);
                                     w1 = bgrat.w;
                                     if (bgrat.ierr != 0) {
                                         ierr = 8;
@@ -428,7 +405,7 @@ public class TOMS708 {
 
                                 /* else if none of the above L180: */
                                 w = basym(a0, b0, lambda, eps * 100.0, logP);
-                                w1 = logP ? log1Exp(w) : 0.5 - w + 0.5;
+                                w1 = logP ? DPQ.rlog1exp(w) : 0.5 - w + 0.5;
                                 debugPrintf("  b0 >= a0 > 100; lambda <= a0 * 0.03: *w:= basym(*) =%.15f\n", w);
                                 break L_end;
 
@@ -438,19 +415,19 @@ public class TOMS708 {
 
                         case L_w_bpser: // was L100
                             w = bpser(a0, b0, x0, eps, logP);
-                            w1 = logP ? log1Exp(w) : 0.5 - w + 0.5;
+                            w1 = logP ? DPQ.rlog1exp(w) : 0.5 - w + 0.5;
                             debugPrintf(" L_w_bpser: *w := bpser(*) = %.1fg\n", w);
                             break L_end;
 
                         case L_w1_bpser:  // was L110
                             w1 = bpser(b0, a0, y0, eps, logP);
-                            w = logP ? log1Exp(w1) : 0.5 - w1 + 0.5;
+                            w = logP ? DPQ.rlog1exp(w1) : 0.5 - w1 + 0.5;
                             debugPrintf(" L_w1_bpser: *w1 := bpser(*) = %.15f\n", w1);
                             break L_end;
 
                         case L_bfrac:
                             w = bfrac(a0, b0, x0, y0, lambda, eps * 15.0, logP);
-                            w1 = logP ? log1Exp(w) : 0.5 - w + 0.5;
+                            w1 = logP ? DPQ.rlog1exp(w) : 0.5 - w + 0.5;
                             debugPrintf(" L_bfrac: *w := bfrac(*) = %f\n", w);
                             break L_end;
 
@@ -466,7 +443,7 @@ public class TOMS708 {
                             w = bup(b0, a0, y0, x0, n, eps, false);
 
                             debugPrintf(" L140: *w := bup(b0=%g,..) = %.15f; ", b0, w);
-                            if (w < DBL_MIN && logP) {
+                            if (w < MathConstants.DBL_MIN && logP) {
                                 /* do not believe it; try bpser() : */
                                 /* revert: */b0 += n;
                                 /* which is only valid if b0 <= 1 || b0*x0 <= 0.7 */
@@ -524,7 +501,7 @@ public class TOMS708 {
                             // *w1 = log(w1) already; w = 1 - w1 ==> log(w) = log(1 - w1) = log(1 -
                             // exp(*w1))
                             if (logP) {
-                                w = log1Exp(w1);
+                                w = DPQ.rlog1exp(w1);
                             } else {
                                 w = /* 1 - exp(*w1) */-Math.expm1(w1);
                                 w1 = Math.exp(w1);
@@ -594,7 +571,7 @@ public class TOMS708 {
             // exp(a*lnx) underflows for large (a * lnx); e.g. large a ==> using log_r := log(r):
             // r = r1 * exp(a * lnx) * exp(bm1 * 0.5 * lnx);
             // log(r)=log(b) + log1p(gam1(b)) + b * log(z) + (a * lnx) + (bm1 * 0.5 * lnx),
-            double logR = Math.log(b) + log1p(gam1(b)) + b * Math.log(z) + nu * lnx;
+            double logR = Math.log(b) + RMath.log1p(gam1(b)) + b * Math.log(z) + nu * lnx;
             // FIXME work with log_u = log(u) also when log_p=FALSE (??)
             // u is 'factored out' from the expansion {and multiplied back, at the end}:
             double logU = logR - (algdiv(b, a) + b * Math.log(nu)); // algdiv(b,a) =
@@ -613,7 +590,7 @@ public class TOMS708 {
             double l = // := *w/u .. but with care: such that it also works when u underflows to 0:
                             logW ? ((w == Double.NEGATIVE_INFINITY) ? 0. : Math.exp(w - logU)) : ((w == 0.) ? 0. : Math.exp(Math.log(w) - logU));
 
-            debugPrintf(" bgrat(a=%f, b=%f, x=%f, *)\n -> u=%f, l='w/u'=%f, ", a, b, x, u, l);
+            debugPrintf(" bgrat(a=%f, b=%f, x=%f, *)\n -> u=%f, l='w/u'=%f, \n", a, b, x, u, l);
 
             double qR = gratR(b, z, logR, eps); // = q/r of former grat1(b,z, r, &p, &q)
             double v = 0.25 / (nu * nu);
@@ -662,7 +639,6 @@ public class TOMS708 {
             } else {
                 w += (u0 ? Math.exp(logU + Math.log(sum)) : u * sum);
             }
-            return;
         } /* bgrat */
     }
 
@@ -713,7 +689,7 @@ public class TOMS708 {
         } while (fabs(c) > tol);
 
         if (logP) {
-            ans += log1p(a * s);
+            ans += RMath.log1p(a * s);
         } else {
             ans *= a * s + 1.0;
         }
@@ -831,7 +807,7 @@ public class TOMS708 {
 
                     if (logP) {
                         /* FIXME? potential for improving log(t) */
-                        ans = z + log(a0 / a) + log1p(gam1(b0)) - log(t);
+                        ans = z + log(a0 / a) + RMath.log1p(gam1(b0)) - log(t);
                     } else {
                         ans = exp(z) * (a0 / a) * (gam1(b0) + 1.0) / t;
                     }
@@ -871,14 +847,14 @@ public class TOMS708 {
         } while (n < 1e7 && fabs(w) > tol);
         if (fabs(w) > tol) { // the series did not converge (in time)
             // warn only when the result seems to matter:
-            if ((logP && !(a * sum > -1. && fabs(log1p(a * sum)) < eps * fabs(ans))) || (!logP && fabs(a * sum + 1) != 1.)) {
+            if ((logP && !(a * sum > -1. && fabs(RMath.log1p(a * sum)) < eps * fabs(ans))) || (!logP && fabs(a * sum + 1) != 1.)) {
                 emitWarning(" bpser(a=%f, b=%f, x=%f,...) did not converge (n=1e7, |w|/tol=%f > 1; A=%f)", a, b, x, fabs(w) / tol, ans);
             }
         }
         debugPrintf("  -> n=%d iterations, |w|=%f %s %f=tol:=eps/a ==> a*sum=%f\n", (int) n, fabs(w), (fabs(w) > tol) ? ">!!>" : "<=", tol, a * sum);
         if (logP) {
             if (a * sum > -1.0) {
-                ans += log1p(a * sum);
+                ans += RMath.log1p(a * sum);
             } else {
                 ans = ML_NEGINF;
             }
@@ -1115,7 +1091,7 @@ public class TOMS708 {
 
                 double c = (gam1(a) + 1.0) * (gam1(b) + 1.0) / z;
                 /* FIXME? log(a0*c)= log(a0)+ log(c) and that is improvable */
-                return (logP ? eZ + log(a0 * c) - log1p(a0 / b0) : eZ * (a0 * c) / (a0 / b0 + 1.0));
+                return (logP ? eZ + log(a0 * c) - RMath.log1p(a0 / b0) : eZ * (a0 * c) / (a0 / b0 + 1.0));
             }
 
             /* else : ALGORITHM FOR 1 < b0 < 8 */
@@ -1141,7 +1117,7 @@ public class TOMS708 {
                 t = gam1(apb) + 1.0;
             }
 
-            return (logP ? log(a0) + z + log1p(gam1(b0)) - log(t) : a0 * exp(z) * (gam1(b0) + 1.0) / t);
+            return (logP ? log(a0) + z + RMath.log1p(gam1(b0)) - log(t) : a0 * exp(z) * (gam1(b0) + 1.0) / t);
 
         } else {
             /* ----------------------------------------------------------------------- */
@@ -1181,7 +1157,7 @@ public class TOMS708 {
 
             double z = logP ? -(a * u + b * v) : exp(-(a * u + b * v));
 
-            return (logP ? -M_LN_SQRT_2PI + .5 * log(b * x0) + z - bcorr(a, b) : INV_SQRT_2_PI * sqrt(b * x0) * z * exp(-bcorr(a, b)));
+            return (logP ? -M_LN_SQRT_2PI + .5 * log(b * x0) + z - bcorr(a, b) : MathConstants.INV_SQRT_2_PI * sqrt(b * x0) * z * exp(-bcorr(a, b)));
         }
     } /* brcomp */
 
@@ -1248,9 +1224,9 @@ public class TOMS708 {
                     z = gam1(apb) + 1.0;
                 }
                 // L50:
-                double c = giveLog ? log1p(gam1(a)) + log1p(gam1(b)) - log(z) : (gam1(a) + 1.0) * (gam1(b) + 1.0) / z;
+                double c = giveLog ? RMath.log1p(gam1(a)) + RMath.log1p(gam1(b)) - log(z) : (gam1(a) + 1.0) * (gam1(b) + 1.0) / z;
                 debugPrintf(" brcmp1(mu,a,b,*): a0 < 1, b0 <= 1;  c=%.15f\n", c);
-                return giveLog ? ans + log(a0) + c - log1p(a0 / b0) : ans * (a0 * c) / (a0 / b0 + 1.0);
+                return giveLog ? ans + log(a0) + c - RMath.log1p(a0 / b0) : ans * (a0 * c) / (a0 / b0 + 1.0);
             }
             // else: algorithm for a0 < 1 < b0 < 8
             // L60:
@@ -1278,7 +1254,7 @@ public class TOMS708 {
             }
             debugPrintf(" brcmp1(mu,a,b,*): a0 < 1 < b0 < 8;  t=%.15f\n", t);
             // L72:
-            return giveLog ? log(a0) + esum(mu, z, true) + log1p(gam1(b0)) - log(t) : a0 * esum(mu, z, false) * (gam1(b0) + 1.0) / t;
+            return giveLog ? log(a0) + esum(mu, z, true) + RMath.log1p(gam1(b0)) - log(t) : a0 * esum(mu, z, false) * (gam1(b0) + 1.0) / t;
 
         } else {
 
@@ -1302,7 +1278,7 @@ public class TOMS708 {
                 y0 = 1.0 / (h + 1.0);
                 lambda = a - (a + b) * x;
             }
-            double lx0 = -log1p(b / a); // in both cases
+            double lx0 = -RMath.log1p(b / a); // in both cases
 
             debugPrintf(" brcmp1(mu,a,b,*): a,b >= 8;  x0=%.15f, lx0=log(x0)=%.15f\n", x0, lx0);
             // L110:
@@ -1327,7 +1303,7 @@ public class TOMS708 {
 
             // L130:
             double z = esum(mu, -(a * u + b * v), giveLog);
-            return giveLog ? log(INV_SQRT_2_PI) + (log(b) + lx0) / 2. + z - bcorr(a, b) : INV_SQRT_2_PI * sqrt(b * x0) * z * exp(-bcorr(a, b));
+            return giveLog ? log(MathConstants.INV_SQRT_2_PI) + (log(b) + lx0) / 2. + z - bcorr(a, b) : MathConstants.INV_SQRT_2_PI * sqrt(b * x0) * z * exp(-bcorr(a, b));
         }
     } /* brcmp1 */
 
diff --git a/com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/stats/Unif.java b/com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/stats/Unif.java
new file mode 100644
index 0000000000000000000000000000000000000000..b708907b8ec250a468ea69465e2269a46144979f
--- /dev/null
+++ b/com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/stats/Unif.java
@@ -0,0 +1,114 @@
+/*
+ * This material is distributed under the GNU General Public License
+ * Version 2. You may review the terms of this license at
+ * http://www.gnu.org/licenses/gpl-2.0.html
+ *
+ * Copyright (C) 1998 Ross Ihaka
+ * Copyright (c) 2000-2006, The R Core Team
+ * Copyright (c) 2013, 2016, Oracle and/or its affiliates
+ *
+ * All rights reserved.
+ */
+package com.oracle.truffle.r.library.stats;
+
+import com.oracle.truffle.api.profiles.BranchProfile;
+import com.oracle.truffle.api.profiles.ConditionProfile;
+import com.oracle.truffle.api.profiles.ValueProfile;
+import com.oracle.truffle.r.library.stats.DPQ.EarlyReturn;
+import com.oracle.truffle.r.library.stats.RandGenerationFunctions.RandFunction2_Double;
+import com.oracle.truffle.r.library.stats.RandGenerationFunctions.RandomNumberProvider;
+import com.oracle.truffle.r.library.stats.StatsFunctions.Function3_1;
+import com.oracle.truffle.r.library.stats.StatsFunctions.Function3_2;
+import com.oracle.truffle.r.runtime.RRuntime;
+
+public final class Unif {
+    private Unif() {
+        // only static members
+    }
+
+    public static final class Runif extends RandFunction2_Double {
+        private final BranchProfile errorProfile = BranchProfile.create();
+        private final ConditionProfile minEqualsMaxProfile = ConditionProfile.createBinaryProfile();
+        private final ValueProfile minValueProfile = ValueProfile.createEqualityProfile();
+        private final ValueProfile maxValueProfile = ValueProfile.createEqualityProfile();
+
+        @Override
+        public double execute(double minIn, double maxIn, RandomNumberProvider rand) {
+            double min = minValueProfile.profile(minIn);
+            double max = maxValueProfile.profile(maxIn);
+            if (!RRuntime.isFinite(min) || !RRuntime.isFinite(max) || max < min) {
+                errorProfile.enter();
+                return RMathError.defaultError();
+            }
+            if (minEqualsMaxProfile.profile(min == max)) {
+                return min;
+            }
+            return min + rand.unifRand() * (max - min);
+        }
+    }
+
+    public static final class PUnif implements Function3_2 {
+        @Override
+        public double evaluate(double x, double min, double max, boolean lowerTail, boolean logP) {
+            if (Double.isNaN(x) || Double.isNaN(min) || Double.isNaN(max)) {
+                return x + min + max;
+            }
+            if (max < min || !Double.isFinite(min) || !Double.isFinite(max)) {
+                return RMathError.defaultError();
+            }
+            if (x >= max) {
+                return DPQ.rdt1(lowerTail, logP);
+            }
+            if (x <= min) {
+                return DPQ.rdt0(lowerTail, logP);
+            }
+            if (lowerTail) {
+                return DPQ.rdval((x - min) / (max - min), logP);
+            } else {
+                return DPQ.rdval((max - x) / (max - min), logP);
+            }
+        }
+    }
+
+    public static final class DUnif implements Function3_1 {
+        @Override
+        public double evaluate(double x, double min, double max, boolean giveLog) {
+            if (Double.isNaN(x) || Double.isNaN(min) || Double.isNaN(max)) {
+                return x + min + max;
+            }
+            if (max <= min) {
+                return RMathError.defaultError();
+            }
+            if (min <= x && x <= max) {
+                return giveLog ? -Math.log(max - min) : 1. / (max - min);
+            }
+            return DPQ.rd0(giveLog);
+        }
+    }
+
+    public static final class QUnif implements Function3_2 {
+
+        @Override
+        public double evaluate(double p, double min, double max, boolean lowerTail, boolean logP) {
+            if (Double.isNaN(p) || Double.isNaN(min) || Double.isNaN(max)) {
+                return p + min + max;
+            }
+
+            try {
+                DPQ.rqp01check(p, logP);
+            } catch (EarlyReturn e) {
+                return e.result;
+            }
+
+            if (max < min || !Double.isFinite(min) || !Double.isFinite(max)) {
+                return RMathError.defaultError();
+            }
+
+            if (max == min) {
+                return min;
+            }
+
+            return min + DPQ.rdtqiv(p, lowerTail, logP) * (max - min);
+        }
+    }
+}
diff --git a/com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/stats/Wilcox.java b/com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/stats/Wilcox.java
index 006474114406a883f3eecd34dd174f20d8c847b0..85ba6659908e2ab0748b1ff367a249906258f31a 100644
--- a/com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/stats/Wilcox.java
+++ b/com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/stats/Wilcox.java
@@ -19,27 +19,30 @@ import com.oracle.truffle.r.runtime.RError;
 import com.oracle.truffle.r.runtime.RRuntime;
 
 public final class Wilcox {
+    private Wilcox() {
+        // only static members
+    }
 
-    public static final class RWilcox implements RandFunction2_Double {
+    public static final class RWilcox extends RandFunction2_Double {
         @Override
-        public double evaluate(double m, double n, RandomNumberProvider rand) {
+        public double execute(double mIn, double nIn, RandomNumberProvider rand) {
             int i;
             int j;
             int k;
             double r;
 
             /* NaNs propagated correctly */
-            if (Double.isNaN(m) || Double.isNaN(n)) {
-                return (m + n);
+            if (Double.isNaN(mIn) || Double.isNaN(nIn)) {
+                return mIn + nIn;
             }
-            if (!Double.isFinite(m) || !Double.isFinite(n)) {
+            if (!Double.isFinite(mIn) || !Double.isFinite(nIn)) {
                 // GnuR does not check this and tries to allocate the memory, we do check this, but
                 // fail with the same error message for compatibility reasons.
                 throw RError.error(RError.SHOW_CALLER, CALLOC_COULD_NOT_ALLOCATE_INF);
             }
 
-            m = Math.round(m);
-            n = Math.round(n);
+            double m = Math.round(mIn);
+            double n = Math.round(nIn);
             if ((m < 0) || (n < 0)) {
                 // TODO: for some reason the macro in GNUR here returns NA instead of NaN...
                 // return StatsUtil.mlError();
diff --git a/com.oracle.truffle.r.native/fficall/Makefile b/com.oracle.truffle.r.native/fficall/Makefile
index 46b4f1d95fcb7c981511ee1fff0baad3fcaf325b..ee3411055022a526dbc34b3f9475bcbdcdb84cb4 100644
--- a/com.oracle.truffle.r.native/fficall/Makefile
+++ b/com.oracle.truffle.r.native/fficall/Makefile
@@ -33,11 +33,16 @@ endif
 
 .PHONY: all clean
 
+C_LIBNAME := libR$(DYLIB_EXT)
+C_LIB := $(FASTR_LIB_DIR)/$(C_LIBNAME)
 R_LIBNAME := libR$(DYLIB_EXT)
 R_LIB := $(FASTR_LIB_DIR)/$(R_LIBNAME)
 JNIBOOT_LIBNAME := libjniboot$(DYLIB_EXT)
 JNIBOOT_LIB := $(FASTR_LIB_DIR)/$(JNIBOOT_LIBNAME)
 
+FASTR_COMPILERS_DIR := $(FASTR_R_HOME)/mx.fastr/compilers
+HAVE_SULONG := $(shell $(FASTR_COMPILERS_DIR)/have_sulong)
+
 ifeq ($(OS_NAME), Darwin)
 VERSION_FLAGS := -current_version $(R_VERSION) -compatibility_version $(R_VERSION)
 endif
@@ -66,6 +71,9 @@ endif
 jni.done:
 	$(MAKE) -C src/common all
 	$(MAKE) -C src/jni all
+ifeq ($(HAVE_SULONG),yes)
+	$(MAKE) -C src/truffle all
+endif
 	touch jni.done
 
 $(JNIBOOT_LIB): jniboot.done
@@ -81,7 +89,10 @@ jniboot.done:
 clean:
 	$(MAKE) -C src/common clean
 	$(MAKE) -C src/jni clean
+ifeq ($(HAVE_SULONG),yes)
+	$(MAKE) -C src/truffle clean
+endif
 	rm -rf $(R_LIB)
 	rm -rf $(JNIBOOT_LIB)
 	rm -rf jni.done jniboot.done
-	
+
diff --git a/com.oracle.truffle.r.native/fficall/README b/com.oracle.truffle.r.native/fficall/README
deleted file mode 100644
index f065aab650d71840f6f56e1f11fa7deafa194033..0000000000000000000000000000000000000000
--- a/com.oracle.truffle.r.native/fficall/README
+++ /dev/null
@@ -1,57 +0,0 @@
-fficall contains the implementation of the R FFI, as described in https://cran.r-project.org/doc/manuals/r-release/R-exts.html.
-It's actually a bit more than that as it also contains code copied from GnuR, for example that supports graphics or is sufficiently
-simple that it is neither necessary nor desirable to implement in Java. As this has evolved a better name for 'fficall' would be 'main'
-for compatibility with GnuR.
-
- There are four sub-directories:
-   include
-   common
-   jni
-   variable_defs
-
-include
-=======
-
-'include' should be thought as analgous to GnuR's src/include, i.e. internal headers needed by the code in 'src/main'.
-What are trying to do by redefining them here is provide a boundary so that we don't accidently capture code from GnuR that
-is specific to the implementation of GnuR that is different in FastR, e.g., the representation of R objects. Evidently not every
-piece of GnuR code or an internal header has that characteristic but this strategy allows us some control to draw the boundary as
-tight as possible. Obviously we want to avoid duplicating (copying) code, as this requires validating the copy when migrating GnuR versions,
-so there are three levels of implementation choice for the content of the header in this directory:
-
-* Leave empty. This allows a #include to succeed and, if code does not actually use any symbols from the header, is ok.
-* Indirect to the real GnuR header. This is potentially dangerous but a simple default for code that uses symbols from the header.
-* Extract specific definitions from the GnuR header into a cut-down version. While this copies code it may be necessary
-  to avoid unwanted aspects of the GnuR header. In principle this can be done by a 'copy with sed' approach.
-
-The indirection requires the use of the quote form of the #include directive. To avoid using a path that is GnuR version dependent,
-the file gnurheaders.mk provides a make variable GNUR_HEADER_DEFS with a set of appropriate -D CFLAGS.
-
-Ideally, code is always compiled in such a way that headers never implicitly read from GnuR, only via the 'include' directory.
-Unfortunately this cannot always be guaranteed as a directive of the form include "foo.h" (as opposed to include <foo.h>) in the
-GnuR C code will always access a header in the same directory as the code being compiled. I.e., only the angle-bracket form can be controlled
-by the -I compiler flag. If this is a problem, the only solution is to 'copy with sed' the .c file and convert the quote form to the
-angle bracket form.
-
-common
-======
-'common' contains code that has no explicit JNI dependencies and has been extracted for reuse in other implementations. This code is mostly
-copied/included from GnuR. N.B. Some modified files have a "_fastr" suffix to avoid a clash with an existing file in GnuR that would match
-the Makefile rule for compiling directly from the GnuR file.
-
-jni
-===
-'jni' contains the implementation that is based on and has explicit dependencies on Java JNI.
-
-The R FFI is rather baroque and defined in large set of header files in the 'include' directory that is a sibling of 'fficall'.
-In GnuR, the implementation of the functions is spread over the GnuR C files in 'src/main'. To ease navigation of the FastR implementation,
-in general, the implementation of the functions in a header file 'Rxxx.h' is stored in the file 'Rxxx.c'.
-
-The points of entry from Java are defined in the file rfficall.c. Various utility functions are defined in rffiutils.{h,c}.
-
-variable_defs
-=============
-
-The GnuR FFI defines a large number of (extern) variables the defintiions of which, in GnuR, are scattered across the source files.
-In FastR these are collected into one file, variable_defs.h. However, the actual initialization of the variables is, in general, implementation
-dependent. In order to support a JNI and a non-JNI implementation, the file is stored in a seperate directory.
diff --git a/com.oracle.truffle.r.native/fficall/src/common/Makefile b/com.oracle.truffle.r.native/fficall/src/common/Makefile
index c4a7426922c9afb82094e16c6c74cce3c127b4b3..da61c6bf96907dd3197e0c9b1756110d79660779 100644
--- a/com.oracle.truffle.r.native/fficall/src/common/Makefile
+++ b/com.oracle.truffle.r.native/fficall/src/common/Makefile
@@ -35,7 +35,7 @@ OBJ = ../../lib
 GNUR_APPL_C_FILES = pretty.c interv.c
 GNUR_APPL_SRC = $(GNUR_HOME)/src/appl
 # the Fortran sources are not recompiled, just copied
-GNUR_APPL_F_OBJECTS := $(wildcard $(GNUR_APPL_SRC)/d*.o)
+GNUR_APPL_F_OBJECTS := $(wildcard $(GNUR_APPL_SRC)/d*.o $(GNUR_APPL_SRC)/d*.ll)
 
 GNUR_MAIN_C_FILES = colors.c devices.c engine.c format.c graphics.c plot.c plot3d.c plotmath.c rlocale.c sort.c
 GNUR_MAIN_SRC = $(GNUR_HOME)/src/main
diff --git a/com.oracle.truffle.r.native/fficall/src/jni/README.md b/com.oracle.truffle.r.native/fficall/src/jni/README.md
deleted file mode 100644
index 244e2df7a9e6bbaf3b3d85f7362af7707e179f04..0000000000000000000000000000000000000000
--- a/com.oracle.truffle.r.native/fficall/src/jni/README.md
+++ /dev/null
@@ -1,12 +0,0 @@
-# Notes on the JNI implementation
-
-## JNI References
-
-Java object values are passed to native code using JNI local references that are valid for the duration of the call. The reference protects the object from garbage collection. Evidently if native code holds on to a local reference by storing it in a native variable,
-that object might be collected, possibly causing incorrect behavior (at best) later in the execution. It is possible to convert a local reference to a global reference that preserves the object across multiple JNI calls but this risks preventing objects from being collected. The global variables defined in the R FFI, e.g. R_NilValue are necessarily handled as global references. However, by default, other values are left as local references, although this can be changed by setting the variable alwaysUseGlobal in rffiutils.c to a non-zero value.
-
-## Vector Content Copying
-
-The R FFI provides access to vector contents as raw C pointers, e.g., int *. This requires the use of the JNI functions to access/copy the underlying data. In addition it requires  that multiple calls on the same SEXP always return the same raw pointer.
-Similar to the discussion on JNI references, the raw data is released at the end of the call. There is currently no provision to retain this data across multiple JNI calls.
-
diff --git a/com.oracle.truffle.r.native/fficall/src/jni/Rembedded.c b/com.oracle.truffle.r.native/fficall/src/jni/Rembedded.c
index 11bfb92d75d0e34e4117a7ad926a9ec098ba92c4..22ad74dcdfdec1f899db788decbb88905e35ee15 100644
--- a/com.oracle.truffle.r.native/fficall/src/jni/Rembedded.c
+++ b/com.oracle.truffle.r.native/fficall/src/jni/Rembedded.c
@@ -645,17 +645,17 @@ SEXP R_getContextSrcRef(CTXT context) {
 int R_insideBrowser() {
 	JNIEnv *jniEnv = getEnv();
 	jmethodID methodID = checkGetMethodID(jniEnv, UpCallsRFFIClass, "R_insideBrowser", "()I", 0);
-    return (*jniEnv)->CallStaticIntMethod(jniEnv, UpCallsRFFIClass, methodID);
+    return (*jniEnv)->CallIntMethod(jniEnv, UpCallsRFFIObject, methodID);
 }
 
 int R_isGlobal(CTXT context) {
 	JNIEnv *jniEnv = getEnv();
 	jmethodID methodID = checkGetMethodID(jniEnv, UpCallsRFFIClass, "R_isGlobal", "(Ljava/lang/Object;)I", 0);
-    return (*jniEnv)->CallStaticIntMethod(jniEnv, UpCallsRFFIClass, methodID, context);
+    return (*jniEnv)->CallIntMethod(jniEnv, UpCallsRFFIObject, methodID, context);
 }
 
 int R_isEqual(void* x, void* y) {
 	JNIEnv *jniEnv = getEnv();
 	jmethodID methodID = checkGetMethodID(jniEnv, UpCallsRFFIClass, "R_isEqual", "(Ljava/lang/Object;Ljava/lang/Object;)I", 0);
-    return (*jniEnv)->CallStaticIntMethod(jniEnv, UpCallsRFFIClass, methodID, x, y);
+    return (*jniEnv)->CallIntMethod(jniEnv, UpCallsRFFIObject, methodID, x, y);
 }
diff --git a/com.oracle.truffle.r.native/fficall/src/jni/rffiutils.c b/com.oracle.truffle.r.native/fficall/src/jni/rffiutils.c
index 69d19f2aec5742fcbc96b2bd11340a324ccf3bcf..2ab54e4fda0141f22c8e2d6d34313e63cd8798d8 100644
--- a/com.oracle.truffle.r.native/fficall/src/jni/rffiutils.c
+++ b/com.oracle.truffle.r.native/fficall/src/jni/rffiutils.c
@@ -88,7 +88,7 @@ static jmp_buf* callErrorJmpBufTable[CALLDEPTH_STACK_SIZE];
 
 void init_utils(JNIEnv *env, jobject upCallsInstance) {
 	curenv = env;
-	UpCallsRFFIClass = (*env)->GetObjectClass(env, upCallsInstance);
+	UpCallsRFFIClass = (*env)->NewGlobalRef(env, (*env)->GetObjectClass(env, upCallsInstance));
 	UpCallsRFFIObject = (*env)->NewGlobalRef(env, upCallsInstance);
 	if (TRACE_ENABLED && traceFile == NULL) {
 		if (!isEmbedded) {
diff --git a/com.oracle.truffle.r.native/fficall/src/jni/variables.c b/com.oracle.truffle.r.native/fficall/src/jni/variables.c
index aaf00d68fee482eaa1fbae06c1421eb1593b189e..10fb96f8e8134669890a83683a9fe6677e5b8c38 100644
--- a/com.oracle.truffle.r.native/fficall/src/jni/variables.c
+++ b/com.oracle.truffle.r.native/fficall/src/jni/variables.c
@@ -65,6 +65,23 @@ CTXT FASTR_GlobalContext() {
     return addGlobalRef(env, res, 0);
 }
 
+static const char *R_Home_local;
+static void *R_NilValue_local;
+static void *R_UnboundValue_local;
+
+char *FASTR_R_Home() {
+	return (char *)R_Home_local;
+}
+
+SEXP FASTR_R_NilValue() {
+	return R_NilValue_local;
+}
+
+SEXP FASTR_R_UnboundValue() {
+	return R_UnboundValue_local;
+}
+
+
 void init_variables(JNIEnv *env, jobjectArray initialValues) {
 	// initialValues is an array of enums
 	jclass enumClass = (*env)->GetObjectClass(env, (*env)->GetObjectArrayElement(env, initialValues, 0));
@@ -93,7 +110,7 @@ void init_variables(JNIEnv *env, jobjectArray initialValues) {
 		jobject value = (*env)->CallObjectMethod(env, variable, getValueMethodID);
 		if (value != NULL) {
 			if (strcmp(nameChars, "R_Home") == 0) {
-				R_Home = (*env)->GetStringUTFChars(env, value, NULL);
+				R_Home_local = (*env)->GetStringUTFChars(env, value, NULL);
 			} else if (strcmp(nameChars, "R_NaN") == 0) {
 				R_NaN = (*env)->CallDoubleMethod(env, value, doubleValueMethodID);
 			} else if (strcmp(nameChars, "R_PosInf") == 0) {
@@ -109,9 +126,9 @@ void init_variables(JNIEnv *env, jobjectArray initialValues) {
 				if (strcmp(nameChars, "R_EmptyEnv") == 0) {
 					R_EmptyEnv = ref;
 				} else if (strcmp(nameChars, "R_NilValue") == 0) {
-					R_NilValue = ref;
+					R_NilValue_local = ref;
 				} else if (strcmp(nameChars, "R_UnboundValue") == 0) {
-					R_UnboundValue = ref;
+					R_UnboundValue_local = ref;
 				} else if (strcmp(nameChars, "R_MissingArg") == 0) {
 					R_MissingArg = ref;
 				} else if (strcmp(nameChars, "R_Bracket2Symbol") == 0) {
diff --git a/com.oracle.truffle.r.native/fficall/src/truffle/Makefile b/com.oracle.truffle.r.native/fficall/src/truffle/Makefile
new file mode 100644
index 0000000000000000000000000000000000000000..f493f5f594d809918fe148e508e6384ae39e9fcb
--- /dev/null
+++ b/com.oracle.truffle.r.native/fficall/src/truffle/Makefile
@@ -0,0 +1,114 @@
+#
+# Copyright (c) 2014, 2016, Oracle and/or its affiliates. All rights reserved.
+# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+#
+# This code is free software; you can redistribute it and/or modify it
+# under the terms of the GNU General Public License version 2 only, as
+# published by the Free Software Foundation.
+#
+# This code is distributed in the hope that it will be useful, but WITHOUT
+# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+# FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+# version 2 for more details (a copy is included in the LICENSE file that
+# accompanied this code).
+#
+# You should have received a copy of the GNU General Public License version
+# 2 along with this work; if not, write to the Free Software Foundation,
+# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+#
+# Please 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 compiles everything in this directory, plus all the code in ../common,
+# including the code referenced in common from GnuR, with the -DFASTR_LLVM flag.
+# This creates an object file with no compiled C/Fortan code, just the equivalent LLVM IR
+# Since, at present, the resulting shared library (libR) must include both the real and the dummy
+# object files, we have to avoid a name clash on the object file,which we achieve by appending
+# "_llvm" to the name of the object file. The wrapper compilers use this name to create the
+# symbol that is looked up to find the LLVM IR at runtime.
+
+# N.B. -g -O2 (which is the FFLAGS default from platform.mk) is currently suppressed
+# due to sulong limitations
+
+ifneq ($(MAKECMDGOALS),clean)
+include $(TOPDIR)/platform.mk
+endif
+
+.PHONY: all clean
+
+include ../include/gnurheaders.mk
+
+# location of compiled code (.o files)
+OBJ = ../../lib
+
+GNUR_APPL_C_FILES = pretty.c interv.c
+GNUR_APPL_SRC = $(GNUR_HOME)/src/appl
+GNUR_APPL_F_FILES := $(wildcard $(GNUR_APPL_SRC)/d*.f)
+
+GNUR_MAIN_C_FILES = colors.c devices.c engine.c format.c graphics.c plot.c plot3d.c plotmath.c rlocale.c sort.c
+GNUR_MAIN_SRC = $(GNUR_HOME)/src/main
+
+GNUR_C_OBJECTS := $(addprefix $(OBJ)/, $(GNUR_APPL_C_FILES:.c=.o) $(GNUR_MAIN_C_FILES:.c=.o))
+LLVM_GNUR_C_OBJECTS := $(GNUR_C_OBJECTS:.o=_llvm.o)
+#$(info LLVM_GNUR_C_OBJECTS: $(LLVM_GNUR_C_OBJECTS))
+
+GNUR_F_OBJECTS := $(addprefix $(OBJ)/, $(notdir $(GNUR_APPL_F_FILES:.f=.o)))
+LLVM_GNUR_F_OBJECTS := $(GNUR_F_OBJECTS:.o=_llvm.o)
+#$(info LLVM_GNUR_F_OBJECTS: $(LLVM_GNUR_F_OBJECTS))
+
+C_HDRS := $(wildcard *.h)
+
+LOCAL_C_SOURCES := $(wildcard *.c) 
+COMMON_C_SOURCES := $(wildcard ../common/*.c)
+C_SOURCES := $(LOCAL_C_SOURCES) $(COMMON_C_SOURCES)
+LOCAL_C_OBJECTS := $(addprefix $(OBJ)/, $(LOCAL_C_SOURCES:.c=.o))
+COMMON_C_OBJECTS := $(addprefix $(OBJ)/, $(notdir $(COMMON_C_SOURCES:.c=.o)))
+C_OBJECTS := $(LOCAL_C_OBJECTS) $(COMMON_C_OBJECTS)
+LLVM_C_OBJECTS := $(C_OBJECTS:.o=_llvm.o)
+#$(info LLVM_C_OBJECTS=$(LLVM_C_OBJECTS))
+
+SULONG_DIR = $(abspath $(FASTR_R_HOME)/../sulong)
+
+SULONG_INCLUDES = -I$(SULONG_DIR)/include
+FFI_INCLUDES = -I$(TOPDIR)/include
+LOCAL_INCLUDES = -I . -I $(abspath ../include)
+
+INCLUDES := $(LOCAL_INCLUDES) $(FFI_INCLUDES) $(SULONG_INCLUDES)
+
+CFLAGS := $(CFLAGS) -DFASTR_LLVM
+#FFLAGS := $(FFLAGS) -DFASTR_LLVM
+FFLAGS := -DFASTR_LLVM
+
+# uncomment to see exactly where headers are being read from
+#CFLAGS := $(CFLAGS) -H
+
+all: Makefile $(LLVM_C_OBJECTS) $(LLVM_GNUR_COBJECTS) $(LLVM_GNUR_F_OBJECTS)
+
+$(C_OBJECTS): | $(OBJ)
+
+$(GNUR_C_OBJECTS): | $(OBJ)
+
+$(GNUR_F_OBJECTS): | $(OBJ)
+
+$(OBJ):
+	mkdir -p $(OBJ)
+
+$(OBJ)/%_llvm.o: $(GNUR_APPL_SRC)/%.c
+	$(CC) $(CFLAGS) $(INCLUDES) $(GNUR_HEADER_DEFS) $(SUPPRESS_WARNINGS) -c $< -o $@
+
+$(OBJ)/%_llvm.o: $(GNUR_MAIN_SRC)/%.c
+	$(CC) $(CFLAGS) $(INCLUDES) $(GNUR_HEADER_DEFS) $(SUPPRESS_WARNINGS) -c $< -o $@
+
+$(OBJ)/%_llvm.o: %.c $(FASTR_NATIVE_DIR)/include/Rinternals.h rffiutils.h
+	$(CC) $(CFLAGS) $(INCLUDES) $(GNUR_HEADER_DEFS) -I../variable_defs $(SUPPRESS_WARNINGS) -c $< -o $@
+
+$(OBJ)/%_llvm.o: ../common/%.c $(FASTR_NATIVE_DIR)/include/Rinternals.h
+	$(CC) $(CFLAGS) $(INCLUDES) $(GNUR_HEADER_DEFS) $(SUPPRESS_WARNINGS) -c $< -o $@
+
+$(OBJ)/%_llvm.o: $(GNUR_APPL_SRC)/%.f
+	$(F77) $(FFLAGS) $(FPICFLAGS) -c $< -o $@
+
+clean:
+	rm -rf $(OBJ)
diff --git a/com.oracle.truffle.r.native/fficall/src/truffle/README.md b/com.oracle.truffle.r.native/fficall/src/truffle/README.md
new file mode 100644
index 0000000000000000000000000000000000000000..8ed7f6488940a668caaa87bc059f8e7c9f9fc579
--- /dev/null
+++ b/com.oracle.truffle.r.native/fficall/src/truffle/README.md
@@ -0,0 +1,2 @@
+The C code in this directory is never compiled by the standard C compiler to create compiled object code.
+It is compiled solely to create LLVM IR which is interpreted at runtime. This is controlled by the -DFASTR_LLVM "compiler" flag.
diff --git a/com.oracle.truffle.r.native/fficall/src/truffle/Rdynload_fastr.c b/com.oracle.truffle.r.native/fficall/src/truffle/Rdynload_fastr.c
new file mode 100644
index 0000000000000000000000000000000000000000..45eef643d9a124db2d32f59496e422faaf3387a7
--- /dev/null
+++ b/com.oracle.truffle.r.native/fficall/src/truffle/Rdynload_fastr.c
@@ -0,0 +1,122 @@
+/*
+ * This material is distributed under the GNU General Public License
+ * Version 2. You may review the terms of this license at
+ * http://www.gnu.org/licenses/gpl-2.0.html
+ *
+ * Copyright (c) 1995-2012, The R Core Team
+ * Copyright (c) 2003, The R Foundation
+ * Copyright (c) 2014, 2016, Oracle and/or its affiliates
+ *
+ * All rights reserved.
+ */
+
+// Registering routines from loaded shared libraries - LLVM variant
+
+#include <R_ext/Rdynload.h>
+#include <truffle.h>
+#include <rffiutils.h>
+
+// Must match ordinal value for DLL.NativeSymbolType
+#define C_NATIVE_TYPE 0
+#define CALL_NATIVE_TYPE 1
+#define FORTRAN_NATIVE_TYPE 2
+#define EXTERNAL_NATIVE_TYPE 3
+
+#define IMPORT_PKG_INIT() void *obj = truffle_import_cached("_fastr_rffi_pkginit")
+
+int
+R_registerRoutines(DllInfo *info, const R_CMethodDef * const croutines,
+		   const R_CallMethodDef * const callRoutines,
+		   const R_FortranMethodDef * const fortranRoutines,
+		   const R_ExternalMethodDef * const externalRoutines) {
+	IMPORT_PKG_INIT();
+	int num;
+	if (croutines) {
+		for(num = 0; croutines[num].name != NULL; num++) {;}
+		truffle_invoke(obj, "registerRoutines", info, C_NATIVE_TYPE, num, (long) croutines);
+	}
+	if (callRoutines) {
+		for(num = 0; callRoutines[num].name != NULL; num++) {;}
+		truffle_invoke(obj, "registerRoutines", info, CALL_NATIVE_TYPE, num, (long) callRoutines);
+	}
+	if (fortranRoutines) {
+		for(num = 0; fortranRoutines[num].name != NULL; num++) {;}
+		truffle_invoke(obj, "registerRoutines", info, FORTRAN_NATIVE_TYPE, num, (long) fortranRoutines);
+	}
+	if (externalRoutines) {
+		for(num = 0; externalRoutines[num].name != NULL; num++) {;}
+		truffle_invoke(obj, "registerRoutines", info, EXTERNAL_NATIVE_TYPE, num, (long) externalRoutines);
+	}
+    return 1;
+}
+
+void *PkgInit_setSymbol(int nstOrd, long routinesAddr, int index) {
+	const char *name;
+	void *fun;
+	int numArgs;
+
+	switch (nstOrd) {
+	case C_NATIVE_TYPE: {
+		R_CMethodDef *croutines = (R_CMethodDef *) routinesAddr;
+		name = croutines[index].name;
+		fun = croutines[index].fun;
+		numArgs = croutines[index].numArgs;
+		break;
+	}
+	case CALL_NATIVE_TYPE: {
+		R_CallMethodDef *callRoutines = (R_CallMethodDef *) routinesAddr;
+		name = callRoutines[index].name;
+		fun = callRoutines[index].fun;
+		numArgs = callRoutines[index].numArgs;
+		break;
+	}
+	case FORTRAN_NATIVE_TYPE: {
+		R_FortranMethodDef * fortranRoutines = (R_FortranMethodDef *) routinesAddr;
+		name = fortranRoutines[index].name;
+		fun = fortranRoutines[index].fun;
+		numArgs = fortranRoutines[index].numArgs;
+		break;
+	}
+	case EXTERNAL_NATIVE_TYPE: {
+		R_ExternalMethodDef * externalRoutines = (R_ExternalMethodDef *) routinesAddr;
+		name = externalRoutines[index].name;
+		fun = externalRoutines[index].fun;
+		numArgs = externalRoutines[index].numArgs;
+		break;
+	}
+	}
+	void *nameString = truffle_read_string(name);
+	void *fundesc = truffle_address_to_function(fun);
+	IMPORT_PKG_INIT();
+	void *result = truffle_invoke(obj, "createDotSymbol", nameString, fundesc, numArgs);
+	return result;
+}
+
+void R_RegisterCCallable(const char *package, const char *name, DL_FUNC fptr) {
+	void *packageString = truffle_read_string(package);
+	void *nameString = truffle_read_string(name);
+	IMPORT_PKG_INIT();
+	truffle_invoke(obj, "registerCCallable", packageString, nameString, (long) fptr);
+}
+
+Rboolean R_useDynamicSymbols(DllInfo *dllInfo, Rboolean value) {
+	IMPORT_PKG_INIT();
+	return truffle_invoke_i(obj, "useDynamicSymbols", dllInfo, value);
+}
+
+Rboolean R_forceSymbols(DllInfo *dllInfo, Rboolean value) {
+	IMPORT_PKG_INIT();
+	return truffle_invoke_i(obj, "forceSymbols", dllInfo, value);
+}
+
+DL_FUNC R_GetCCallable(const char *package, const char *name) {
+	unimplemented("R_GetCCallable");
+	return NULL;
+}
+
+DL_FUNC R_FindSymbol(char const *name, char const *pkg,
+		     R_RegisteredNativeSymbol *symbol) {
+    unimplemented("R_FindSymbol");
+    return NULL;
+}
+
diff --git a/com.oracle.truffle.r.native/fficall/src/truffle/Rinternals.c b/com.oracle.truffle.r.native/fficall/src/truffle/Rinternals.c
new file mode 100644
index 0000000000000000000000000000000000000000..d91c866eb705a11d63e948c03a24cfe4d61949f6
--- /dev/null
+++ b/com.oracle.truffle.r.native/fficall/src/truffle/Rinternals.c
@@ -0,0 +1,1124 @@
+/*
+ * Copyright (c) 2015, 2016, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+#include <rffiutils.h>
+#include <truffle.h>
+
+// Most everything in RInternals.h
+
+static char *ensure_truffle_chararray(const char *x);
+static char *ensure_truffle_chararray_n(const char *x, int n);
+
+SEXP Rf_ScalarInteger(int value) {
+	IMPORT_CALLHELPER();
+	return truffle_invoke(obj, "Rf_ScalarInteger", value);
+}
+
+SEXP Rf_ScalarReal(double value) {
+	IMPORT_CALLHELPER();
+	return truffle_invoke(obj, "Rf_ScalarDouble", value);
+}
+
+SEXP Rf_ScalarString(SEXP value) {
+	IMPORT_CALLHELPER();
+	return truffle_invoke(obj, "Rf_ScalarString", value);
+}
+
+SEXP Rf_ScalarLogical(int value) {
+	IMPORT_CALLHELPER();
+	return truffle_invoke(obj, "Rf_ScalarLogical", value);
+}
+
+SEXP Rf_allocVector3(SEXPTYPE t, R_xlen_t len, R_allocator_t* allocator) {
+    if (allocator != NULL) {
+	    return unimplemented("RF_allocVector with custom allocator");
+    }
+	IMPORT_CALLHELPER();
+	return truffle_invoke(obj, "Rf_allocateVector", t, len);
+}
+
+SEXP Rf_allocArray(SEXPTYPE t, SEXP dims) {
+	return unimplemented("Rf_allocArray");
+}
+
+SEXP Rf_alloc3DArray(SEXPTYPE t, int x, int y, int z) {
+	return unimplemented("Rf_alloc3DArray");
+}
+
+SEXP Rf_allocMatrix(SEXPTYPE mode, int nrow, int ncol) {
+	return unimplemented("Rf_allocMatrix");
+}
+
+SEXP Rf_allocList(int x) {
+	return unimplemented("Rf_allocList)");
+}
+
+SEXP Rf_allocSExp(SEXPTYPE t) {
+	return unimplemented("Rf_allocSExp");
+}
+
+SEXP Rf_cons(SEXP car, SEXP cdr) {
+	return unimplemented("Rf_cons");
+}
+
+void Rf_defineVar(SEXP symbol, SEXP value, SEXP rho) {
+	unimplemented("Rf_defineVar");
+}
+
+void Rf_setVar(SEXP x, SEXP y, SEXP z) {
+    unimplemented("Rf_setVar");
+}
+
+SEXP Rf_dimgets(SEXP x, SEXP y) {
+	return unimplemented("Rf_dimgets");
+}
+
+SEXP Rf_dimnamesgets(SEXP x, SEXP y) {
+	return unimplemented("Rf_dimnamesgets");
+}
+
+SEXP Rf_eval(SEXP expr, SEXP env) {
+	return unimplemented("Rf_eval");
+}
+
+SEXP Rf_findFun(SEXP symbol, SEXP rho) {
+	return unimplemented("Rf_findFun");
+}
+
+SEXP Rf_findVar(SEXP symbol, SEXP rho) {
+	IMPORT_CALLHELPER();
+    return truffle_invoke(obj, "Rf_findVar", symbol, rho);
+}
+
+SEXP Rf_findVarInFrame(SEXP symbol, SEXP rho) {
+	return unimplemented("Rf_findVarInFrame");
+}
+
+SEXP Rf_getAttrib(SEXP vec, SEXP name) {
+	return unimplemented("Rf_getAttrib");
+}
+
+SEXP Rf_setAttrib(SEXP vec, SEXP name, SEXP val) {
+	return unimplemented("Rf_setAttrib");
+}
+
+SEXP Rf_duplicate(SEXP x) {
+	IMPORT_CALLHELPER();
+    return truffle_invoke(obj, "Rf_duplicate", x, 1);
+}
+
+SEXP Rf_shallow_duplicate(SEXP x) {
+	IMPORT_CALLHELPER();
+    return truffle_invoke(obj, "Rf_duplicate", x, 0);
+}
+
+R_xlen_t Rf_any_duplicated(SEXP x, Rboolean from_last) {
+	return (R_xlen_t) unimplemented("Rf_any_duplicated");
+}
+
+SEXP Rf_duplicated(SEXP x, Rboolean y) {
+	return unimplemented("Rf_duplicated");
+}
+
+SEXP Rf_applyClosure(SEXP x, SEXP y, SEXP z, SEXP a, SEXP b) {
+	return unimplemented("Rf_applyClosure");
+}
+
+void Rf_copyMostAttrib(SEXP x, SEXP y) {
+	unimplemented("Rf_copyMostAttrib");
+}
+
+void Rf_copyVector(SEXP x, SEXP y) {
+	unimplemented("Rf_copyVector");
+}
+
+Rboolean Rf_inherits(SEXP x, const char * klass) {
+	unimplemented("Rf_inherits");
+	return FALSE;
+}
+
+Rboolean Rf_isReal(SEXP x) {
+    return TYPEOF(x) == REALSXP;
+}
+
+Rboolean Rf_isSymbol(SEXP x) {
+    return TYPEOF(x) == SYMSXP;
+}
+
+Rboolean Rf_isComplex(SEXP x) {
+    return TYPEOF(x) == CPLXSXP;
+}
+
+Rboolean Rf_isEnvironment(SEXP x) {
+    return TYPEOF(x) == ENVSXP;
+}
+
+Rboolean Rf_isExpression(SEXP x) {
+    return TYPEOF(x) == EXPRSXP;
+}
+
+Rboolean Rf_isLogical(SEXP x) {
+    return TYPEOF(x) == LGLSXP;
+}
+
+Rboolean Rf_isObject(SEXP s) {
+	unimplemented("Rf_isObject");
+	return FALSE;
+}
+
+void Rf_PrintValue(SEXP x) {
+	unimplemented("Rf_PrintValue");
+}
+
+SEXP Rf_install(const char *name) {
+	IMPORT_CALLHELPER();
+	return truffle_invoke(obj, "Rf_install", ensure_truffle_chararray(name));
+}
+
+SEXP Rf_installChar(SEXP charsxp) {
+	return unimplemented("Rf_installChar");
+}
+
+Rboolean Rf_isNull(SEXP s) {
+	IMPORT_CALLHELPER();
+	return (Rboolean) truffle_invoke_i(obj, "Rf_isNull", s);
+}
+
+Rboolean Rf_isString(SEXP s) {
+	IMPORT_CALLHELPER();
+	return (Rboolean) truffle_invoke_i(obj, "Rf_isString", s);
+}
+
+Rboolean R_cycle_detected(SEXP s, SEXP child) {
+	return (Rboolean) unimplemented("R_cycle_detected");
+}
+
+cetype_t Rf_getCharCE(SEXP x) {
+    // unimplemented("Rf_getCharCE");
+    // TODO: real implementation
+    return CE_NATIVE;
+}
+
+static char *ensure_truffle_chararray(const char *x) {
+	if (truffle_is_truffle_object(x)) {
+		return x;
+	} else {
+		IMPORT_CALLHELPER();
+		return truffle_invoke(obj, "bytesToNativeCharArray", truffle_read_bytes(x));
+	}
+}
+
+char *ensure_truffle_chararray_n(const char *x, int n) {
+	if (truffle_is_truffle_object(x)) {
+		return x;
+	} else {
+		IMPORT_CALLHELPER();
+		return truffle_invoke(obj, "bytesToNativeCharArray", truffle_read_n_bytes(x, n));
+	}
+}
+
+SEXP Rf_mkCharLenCE_truffle(const char *x, cetype_t enc) {
+	// Assumes x is a NativeCharArray
+	IMPORT_CALLHELPER();
+	return truffle_invoke(obj, "Rf_mkCharLenCE", x, enc);
+}
+
+SEXP Rf_mkChar(const char *x) {
+	return Rf_mkCharLenCE_truffle(ensure_truffle_chararray(x), CE_NATIVE);
+}
+
+SEXP Rf_mkCharCE(const char *x, cetype_t y) {
+	return Rf_mkCharLenCE_truffle(ensure_truffle_chararray(x), y);
+}
+
+SEXP Rf_mkCharLen(const char *x, int y) {
+	return Rf_mkCharLenCE(x, y, CE_NATIVE);
+}
+
+SEXP Rf_mkCharLenCE(const char *x, int len, cetype_t enc) {
+	return Rf_mkCharLenCE_truffle(ensure_truffle_chararray_n(x, len), enc);
+}
+
+const char *Rf_reEnc(const char *x, cetype_t ce_in, cetype_t ce_out, int subst) {
+	// TODO proper implementation
+	return x;
+}
+
+SEXP Rf_mkString(const char *s) {
+	return ScalarString(Rf_mkChar(s));
+}
+
+int Rf_ncols(SEXP x) {
+	unimplemented("Rf_ncols");
+	return 0;
+}
+
+int Rf_nrows(SEXP x) {
+	unimplemented("Rf_nrows");
+	return 0;
+}
+
+
+SEXP Rf_protect(SEXP x) {
+	return x;
+}
+
+void Rf_unprotect(int x) {
+	// TODO perhaps we can use this
+}
+
+void R_ProtectWithIndex(SEXP x, PROTECT_INDEX *y) {
+
+}
+
+void R_Reprotect(SEXP x, PROTECT_INDEX y) {
+
+}
+
+
+void Rf_unprotect_ptr(SEXP x) {
+	// TODO perhaps we can use this
+}
+
+#define BUFSIZE 8192
+
+static int Rvsnprintf(char *buf, size_t size, const char  *format, va_list ap)
+{
+    int val;
+    val = vsnprintf(buf, size, format, ap);
+    buf[size-1] = '\0';
+    return val;
+}
+
+
+void Rf_error(const char *format, ...) {
+	// This is a bit tricky. The usual error handling model in Java is "throw RError.error(...)" but
+	// RError.error does quite a lot of stuff including potentially searching for R condition handlers
+	// and, if it finds any, does not return, but throws a different exception than RError.
+	// We definitely need to exit the FFI call and we certainly cannot return to our caller.
+	// So we call CallRFFIHelper.Rf_error to throw the RError exception. When the pending
+	// exception (whatever it is) is observed by JNI, the call to Rf_error will return where we do a
+	// non-local transfer of control back to the entry point (which will cleanup).
+	char buf[8192];
+	va_list(ap);
+	va_start(ap,format);
+	Rvsnprintf(buf, BUFSIZE - 1, format, ap);
+	va_end(ap);
+	unimplemented("Rf_error");
+}
+
+void Rf_errorcall(SEXP x, const char *format, ...) {
+	unimplemented("Rf_errorcall");
+}
+
+void Rf_warningcall(SEXP x, const char *format, ...) {
+	char buf[8192];
+	va_list(ap);
+	va_start(ap,format);
+	Rvsnprintf(buf, BUFSIZE - 1, format, ap);
+	va_end(ap);
+	unimplemented("Rf_warningcall");
+
+}
+
+void Rf_warning(const char *format, ...) {
+	char buf[8192];
+	va_list(ap);
+	va_start(ap,format);
+	Rvsnprintf(buf, BUFSIZE - 1, format, ap);
+	va_end(ap);
+	unimplemented("Rf_warning");
+
+}
+
+void Rprintf(const char *format, ...) {
+	char buf[8192];
+	va_list(ap);
+	va_start(ap,format);
+	Rvsnprintf(buf, BUFSIZE - 1, format, ap);
+	va_end(ap);
+	void *str = truffle_read_string(buf);
+	IMPORT_CALLHELPER();
+	truffle_invoke(obj, "printf", str);
+}
+
+/*
+  REprintf is used by the error handler do not add
+  anything unless you're sure it won't
+  cause problems
+*/
+void REprintf(const char *format, ...)
+{
+	// TODO: determine correct target for this message
+	char buf[8192];
+	va_list(ap);
+	va_start(ap,format);
+	Rvsnprintf(buf, BUFSIZE - 1, format, ap);
+	va_end(ap);
+	unimplemented("REprintf");
+
+}
+
+void Rvprintf(const char *format, va_list args) {
+	unimplemented("Rvprintf");
+}
+void REvprintf(const char *format, va_list args) {
+	unimplemented("REvprintf");
+}
+
+void R_FlushConsole(void) {
+	// ignored
+}
+
+void R_ProcessEvents(void) {
+	unimplemented("R_ProcessEvents");
+}
+
+// Tools package support, not in public API
+
+SEXP R_NewHashedEnv(SEXP parent, SEXP size) {
+	return unimplemented("R_NewHashedEnv");
+}
+
+SEXP Rf_classgets(SEXP x, SEXP y) {
+	return unimplemented("Rf_classgets");
+}
+
+const char *Rf_translateChar(SEXP x) {
+//	unimplemented("Rf_translateChar");
+	// TODO: proper implementation
+	const char *result = CHAR(x);
+//	printf("translateChar: '%s'\n", result);
+	return result;
+}
+
+const char *Rf_translateChar0(SEXP x) {
+	unimplemented("Rf_translateChar0");
+	return NULL;
+}
+
+const char *Rf_translateCharUTF8(SEXP x) {
+	unimplemented("Rf_translateCharUTF8");
+	return NULL;
+}
+
+SEXP R_FindNamespace(SEXP info) {
+	return unimplemented("R_FindNamespace");
+}
+
+SEXP Rf_lengthgets(SEXP x, R_len_t y) {
+	return unimplemented("Rf_lengthgets");
+}
+
+SEXP Rf_xlengthgets(SEXP x, R_xlen_t y) {
+	return unimplemented("Rf_xlengthgets");
+
+}
+
+SEXP Rf_namesgets(SEXP x, SEXP y) {
+	return unimplemented("Rf_namesgets");
+}
+
+SEXP GetOption1(SEXP tag){
+	return unimplemented("GetOption1");
+}
+
+SEXP GetOption(SEXP tag, SEXP rho) {
+    return GetOption1(tag);
+}
+
+int GetOptionCutoff(void)
+{
+    int w;
+    w = asInteger(GetOption1(install("deparse.cutoff")));
+    if (w == NA_INTEGER || w <= 0) {
+	warning(_("invalid 'deparse.cutoff', used 60"));
+	w = 60;
+    }
+    return w;
+}
+
+#define R_MIN_WIDTH_OPT		10
+#define R_MAX_WIDTH_OPT		10000
+#define R_MIN_DIGITS_OPT	0
+#define R_MAX_DIGITS_OPT	22
+
+int GetOptionWidth(void)
+{
+    int w;
+    w = asInteger(GetOption1(install("width")));
+    if (w < R_MIN_WIDTH_OPT || w > R_MAX_WIDTH_OPT) {
+	warning(_("invalid printing width, used 80"));
+	return 80;
+    }
+    return w;
+}
+
+int GetOptionDigits(void)
+{
+    int d;
+    d = asInteger(GetOption1(install("digits")));
+    if (d < R_MIN_DIGITS_OPT || d > R_MAX_DIGITS_OPT) {
+	warning(_("invalid printing digits, used 7"));
+	return 7;
+    }
+    return d;
+}
+
+Rboolean Rf_GetOptionDeviceAsk(void)
+{
+    int ask;
+    ask = asLogical(GetOption1(install("device.ask.default")));
+    if(ask == NA_LOGICAL) {
+	warning(_("invalid value for \"device.ask.default\", using FALSE"));
+	return FALSE;
+    }
+    return ask != 0;
+}
+
+void Rf_gsetVar(SEXP symbol, SEXP value, SEXP rho) {
+	unimplemented("Rf_gsetVar");
+}
+
+SEXP TAG(SEXP e) {
+	IMPORT_CALLHELPER();
+	return truffle_invoke(obj, "TAG", e);
+}
+
+SEXP PRINTNAME(SEXP e) {
+	return unimplemented("PRINTNAME");
+}
+
+SEXP CAR(SEXP e) {
+	IMPORT_CALLHELPER();
+	return truffle_invoke(obj, "CAR", e);
+}
+
+SEXP CDR(SEXP e) {
+	IMPORT_CALLHELPER();
+	return truffle_invoke(obj, "CDR", e);
+}
+
+SEXP CAAR(SEXP e) {
+    unimplemented("CAAR");
+    return NULL;
+}
+
+SEXP CDAR(SEXP e) {
+    unimplemented("CDAR");
+    return NULL;
+}
+
+SEXP CADR(SEXP e) {
+	IMPORT_CALLHELPER();
+	return truffle_invoke(obj, "CADR", e);
+}
+
+SEXP CDDR(SEXP e) {
+	return unimplemented("CDDR");
+}
+
+SEXP CDDDR(SEXP e) {
+    unimplemented("CDDDR");
+    return NULL;
+}
+
+SEXP CADDR(SEXP e) {
+    unimplemented("CADDR");
+    return NULL;
+}
+
+SEXP CADDDR(SEXP e) {
+    unimplemented("CADDDR");
+    return NULL;
+}
+
+SEXP CAD4R(SEXP e) {
+    unimplemented("CAD4R");
+    return NULL;
+}
+
+int MISSING(SEXP x){
+    unimplemented("MISSING");
+    return 0;
+}
+
+void SET_MISSING(SEXP x, int v) {
+    unimplemented("SET_MISSING");
+}
+
+void SET_TAG(SEXP x, SEXP y) {
+	unimplemented("SET_TAG");
+}
+
+SEXP SETCAR(SEXP x, SEXP y) {
+	return unimplemented("SETCAR");
+}
+
+SEXP SETCDR(SEXP x, SEXP y) {
+	return unimplemented("SETCDR");
+}
+
+SEXP SETCADR(SEXP x, SEXP y) {
+    unimplemented("SETCADR");
+    return NULL;
+}
+
+SEXP SETCADDR(SEXP x, SEXP y) {
+    unimplemented("SETCADDR");
+    return NULL;
+}
+
+SEXP SETCADDDR(SEXP x, SEXP y) {
+    unimplemented("SETCADDDR");
+    return NULL;
+}
+
+SEXP SETCAD4R(SEXP e, SEXP y) {
+    unimplemented("SETCAD4R");
+    return NULL;
+}
+
+SEXP FORMALS(SEXP x) {
+    return unimplemented("FORMALS");
+}
+
+SEXP BODY(SEXP x) {
+	return unimplemented("BODY");
+}
+
+SEXP CLOENV(SEXP x) {
+	return unimplemented("CLOENV");
+}
+
+int RDEBUG(SEXP x) {
+    unimplemented("RDEBUG");
+    return 0;
+}
+
+int RSTEP(SEXP x) {
+	unimplemented("RSTEP");
+    return 0;
+}
+
+int RTRACE(SEXP x) {
+	unimplemented("RTRACE");
+    return 0;
+}
+
+void SET_RDEBUG(SEXP x, int v) {
+    unimplemented("SET_RDEBUG");
+}
+
+void SET_RSTEP(SEXP x, int v) {
+    unimplemented("SET_RSTEP");
+}
+
+void SET_RTRACE(SEXP x, int v) {
+    unimplemented("SET_RTRACE");
+}
+
+void SET_FORMALS(SEXP x, SEXP v) {
+    unimplemented("SET_FORMALS");
+}
+
+void SET_BODY(SEXP x, SEXP v) {
+    unimplemented("SET_BODY");
+}
+
+void SET_CLOENV(SEXP x, SEXP v) {
+    unimplemented("SET_CLOENV");
+}
+
+SEXP SYMVALUE(SEXP x) {
+	return unimplemented("SYMVALUE");
+}
+
+SEXP INTERNAL(SEXP x) {
+	return unimplemented("INTERNAL");
+}
+
+int DDVAL(SEXP x) {
+	unimplemented("DDVAL");
+    return 0;
+}
+
+void SET_DDVAL(SEXP x, int v) {
+    unimplemented("SET_DDVAL");
+}
+
+void SET_SYMVALUE(SEXP x, SEXP v) {
+    unimplemented("SET_SYMVALUE");
+}
+
+void SET_INTERNAL(SEXP x, SEXP v) {
+    unimplemented("SET_INTERNAL");
+}
+
+
+SEXP FRAME(SEXP x) {
+	return unimplemented("FRAME");
+}
+
+SEXP ENCLOS(SEXP x) {
+	return unimplemented("ENCLOS");
+}
+
+SEXP HASHTAB(SEXP x) {
+	return unimplemented("HASHTAB");
+}
+
+int ENVFLAGS(SEXP x) {
+	unimplemented("ENVFLAGS");
+    return 0;
+}
+
+void SET_ENVFLAGS(SEXP x, int v) {
+	unimplemented("SET_ENVFLAGS");
+}
+
+void SET_FRAME(SEXP x, SEXP v) {
+    unimplemented("SET_FRAME");
+}
+
+void SET_ENCLOS(SEXP x, SEXP v) {
+	unimplemented("SET_ENCLOS");
+}
+
+void SET_HASHTAB(SEXP x, SEXP v) {
+	unimplemented("SET_HASHTAB");
+}
+
+
+SEXP PRCODE(SEXP x) {
+	return unimplemented("PRCODE");
+}
+
+SEXP PRENV(SEXP x) {
+	unimplemented("PRSEEN");
+    return 0;
+}
+
+SEXP PRVALUE(SEXP x) {
+	return unimplemented("PRVALUE");
+}
+
+int PRSEEN(SEXP x) {
+	return (int) unimplemented("PRSEEN");
+}
+
+void SET_PRSEEN(SEXP x, int v) {
+    unimplemented("SET_PRSEEN");
+}
+
+void SET_PRENV(SEXP x, SEXP v) {
+    unimplemented("SET_PRENV");
+}
+
+void SET_PRVALUE(SEXP x, SEXP v) {
+    unimplemented("SET_PRVALUE");
+}
+
+void SET_PRCODE(SEXP x, SEXP v) {
+    unimplemented("SET_PRCODE");
+}
+
+int LENGTH(SEXP x) {
+	IMPORT_CALLHELPER();
+    return truffle_invoke_i(obj, "LENGTH", x);
+}
+
+int TRUELENGTH(SEXP x){
+    unimplemented("unimplemented");
+    return 0;
+}
+
+
+void SETLENGTH(SEXP x, int v){
+    unimplemented("SETLENGTH");
+}
+
+
+void SET_TRUELENGTH(SEXP x, int v){
+    unimplemented("SET_TRUELENGTH");
+}
+
+
+R_xlen_t XLENGTH(SEXP x){
+    // xlength seems to be used for long vectors (no such thing in FastR at the moment)
+    return LENGTH(x);
+}
+
+
+R_xlen_t XTRUELENGTH(SEXP x){
+	unimplemented("XTRUELENGTH");
+	return 0;
+}
+
+
+int IS_LONG_VEC(SEXP x){
+	unimplemented("IS_LONG_VEC");
+	return 0;
+}
+
+
+int LEVELS(SEXP x){
+	unimplemented("LEVELS");
+	return 0;
+}
+
+
+int SETLEVELS(SEXP x, int v){
+	unimplemented("SETLEVELS");
+	return 0;
+}
+
+int *LOGICAL(SEXP x){
+	IMPORT_CALLHELPER();
+	return (int*) truffle_invoke(obj, "LOGICAL", x);
+}
+
+int *INTEGER(SEXP x){
+	IMPORT_CALLHELPER();
+	return (int*) truffle_invoke(obj, "INTEGER", x);
+}
+
+
+Rbyte *RAW(SEXP x){
+	IMPORT_CALLHELPER();
+	return (int*) truffle_invoke(obj, "RAW", x);
+}
+
+
+double *REAL(SEXP x){
+	IMPORT_CALLHELPER();
+	return (double*) truffle_invoke(obj, "REAL", x);
+}
+
+
+Rcomplex *COMPLEX(SEXP x){
+	return (Rcomplex*) unimplemented("COMPLEX");
+}
+
+
+SEXP STRING_ELT(SEXP x, R_xlen_t i){
+	IMPORT_CALLHELPER();
+	return truffle_invoke(obj, "STRING_ELT", x, i);
+}
+
+
+SEXP VECTOR_ELT(SEXP x, R_xlen_t i){
+	IMPORT_CALLHELPER();
+	return truffle_invoke(obj, "VECTOR_ELT", x, i);
+}
+
+void SET_STRING_ELT(SEXP x, R_xlen_t i, SEXP v){
+	IMPORT_CALLHELPER();
+	truffle_invoke(obj, "SET_STRING_ELT", x, i, v);
+}
+
+
+SEXP SET_VECTOR_ELT(SEXP x, R_xlen_t i, SEXP v){
+	IMPORT_CALLHELPER();
+	return truffle_invoke(obj, "SET_VECTOR_ELT", x, i, v);
+}
+
+
+SEXP *STRING_PTR(SEXP x){
+	return unimplemented("STRING_PTR");
+}
+
+
+SEXP *VECTOR_PTR(SEXP x){
+	return unimplemented("VECTOR_PTR");
+}
+
+SEXP Rf_asChar(SEXP x){
+	IMPORT_CALLHELPER();
+	return truffle_invoke(obj, "Rf_asChar", x);
+}
+
+SEXP Rf_PairToVectorList(SEXP x){
+	return unimplemented("Rf_PairToVectorList");
+}
+
+SEXP Rf_VectorToPairList(SEXP x){
+	return unimplemented("Rf_VectorToPairList");
+}
+
+SEXP Rf_asCharacterFactor(SEXP x){
+	return unimplemented("Rf_VectorToPairList");
+}
+
+int Rf_asLogical(SEXP x){
+	return (int) unimplemented("Rf_asLogical");
+}
+
+int Rf_asInteger(SEXP x) {
+	IMPORT_CALLHELPER();
+    return truffle_invoke_i(obj, "Rf_asInteger", x);
+}
+
+Rcomplex Rf_asComplex(SEXP x){
+	unimplemented("Rf_asLogical");
+	Rcomplex c; return c;
+}
+
+int TYPEOF(SEXP x) {
+	IMPORT_CALLHELPER();
+	return truffle_invoke_i(obj, "TYPEOF", x);
+}
+
+SEXP ATTRIB(SEXP x){
+    unimplemented("ATTRIB");
+    return NULL;
+}
+
+int OBJECT(SEXP x){
+	return (int) unimplemented("OBJECT");
+}
+
+int MARK(SEXP x){
+    return (int) unimplemented("MARK");
+}
+
+int NAMED(SEXP x){
+	IMPORT_CALLHELPER();
+	return truffle_invoke_i(obj, "NAMED", x);
+}
+
+int REFCNT(SEXP x){
+	return (int) unimplemented("REFCNT");
+}
+
+void SET_OBJECT(SEXP x, int v){
+    unimplemented("SET_OBJECT");
+}
+
+void SET_TYPEOF(SEXP x, int v){
+    unimplemented("SET_TYPEOF");
+}
+
+SEXP SET_TYPEOF_FASTR(SEXP x, int v){
+	return unimplemented("SET_TYPEOF_FASTR");
+}
+
+void SET_NAMED(SEXP x, int v){
+    unimplemented("SET_NAMED");
+}
+
+void SET_ATTRIB(SEXP x, SEXP v){
+    unimplemented("SET_ATTRIB");
+}
+
+void DUPLICATE_ATTRIB(SEXP to, SEXP from){
+	unimplemented("DUPLICATE_ATTRIB");
+}
+
+char *dgettext(const char *domainname, const char *msgid) {
+	printf("dgettext: '%s'\n", msgid);
+	return (char*) msgid;
+}
+
+char *dngettext(const char *domainname, const char *msgid, const char * msgid_plural, unsigned long int n) {
+    printf("dngettext: singular - '%s' ; plural - '%s'\n", msgid, msgid_plural);
+    return (char*) (n == 1 ? msgid : msgid_plural);
+}
+
+const char *R_CHAR(SEXP charsxp) {
+	IMPORT_CALLHELPER();
+	return (char *)truffle_invoke(obj, "charSXPToNativeCharArray", charsxp);
+}
+
+void *(R_DATAPTR)(SEXP x) {
+    unimplemented("R_DATAPTR");
+	return NULL;
+}
+
+void R_qsort_I  (double *v, int *II, int i, int j) {
+	unimplemented("R_qsort_I");
+}
+
+void R_qsort_int_I(int *iv, int *II, int i, int j) {
+	unimplemented("R_qsort_int_I");
+}
+
+R_len_t R_BadLongVector(SEXP x, const char *y, int z) {
+	return (R_len_t) unimplemented("R_BadLongVector");
+}
+
+int IS_S4_OBJECT(SEXP x) {
+	return (int) unimplemented("IS_S4_OBJECT");
+}
+
+void SET_S4_OBJECT(SEXP x) {
+	unimplemented("SET_S4_OBJECT");
+}
+void UNSET_S4_OBJECT(SEXP x) {
+	unimplemented("UNSET_S4_OBJECT");
+}
+
+Rboolean R_ToplevelExec(void (*fun)(void *), void *data) {
+	return (Rboolean) unimplemented("R_ToplevelExec");
+}
+
+SEXP R_ExecWithCleanup(SEXP (*fun)(void *), void *data,
+		       void (*cleanfun)(void *), void *cleandata) {
+	return unimplemented("R_ExecWithCleanup");
+}
+
+SEXP R_tryEval(SEXP x, SEXP y, int *z) {
+	return unimplemented("R_tryEval");
+}
+
+SEXP R_tryEvalSilent(SEXP x, SEXP y, int *z) {
+	return unimplemented("R_tryEvalSilent");
+}
+
+double R_atof(const char *str) {
+	unimplemented("R_atof");
+	return 0;
+}
+
+double R_strtod(const char *c, char **end) {
+	unimplemented("R_strtod");
+	return 0;
+}
+
+SEXP R_PromiseExpr(SEXP x) {
+	return unimplemented("R_PromiseExpr");
+}
+
+SEXP R_ClosureExpr(SEXP x) {
+	return unimplemented("R_ClosureExpr");
+}
+
+SEXP R_forceAndCall(SEXP e, int n, SEXP rho) {
+	return unimplemented("R_forceAndCall");
+}
+
+SEXP R_MakeExternalPtr(void *p, SEXP tag, SEXP prot) {
+	IMPORT_CALLHELPER();
+	return truffle_invoke(obj, "R_MakeExternalPtr", (long) p, tag, prot);
+}
+
+void *R_ExternalPtrAddr(SEXP s) {
+	IMPORT_CALLHELPER();
+	return (void*) truffle_invoke_l(obj, "R_ExternalPtrAddr", s);
+}
+
+SEXP R_ExternalPtrTag(SEXP s) {
+	return unimplemented("R_ExternalPtrTag");
+}
+
+SEXP R_ExternalPtrProt(SEXP s) {
+	return unimplemented("R_ExternalPtrProt");
+}
+
+void R_SetExternalPtrAddr(SEXP s, void *p) {
+	unimplemented("R_SetExternalPtrAddr");
+}
+
+void R_SetExternalPtrTag(SEXP s, SEXP tag) {
+	unimplemented("R_SetExternalPtrTag");
+}
+
+void R_SetExternalPtrProt(SEXP s, SEXP p) {
+	unimplemented("R_SetExternalPtrProt");
+}
+
+void R_ClearExternalPtr(SEXP s) {
+	R_SetExternalPtrAddr(s, NULL);
+}
+
+void R_RegisterFinalizer(SEXP s, SEXP fun) {
+	// TODO implement, but not fail for now
+}
+void R_RegisterCFinalizer(SEXP s, R_CFinalizer_t fun) {
+	// TODO implement, but not fail for now
+}
+
+void R_RegisterFinalizerEx(SEXP s, SEXP fun, Rboolean onexit) {
+	// TODO implement, but not fail for now
+
+}
+
+void R_RegisterCFinalizerEx(SEXP s, R_CFinalizer_t fun, Rboolean onexit) {
+	// TODO implement, but not fail for now
+}
+
+void R_RunPendingFinalizers(void) {
+	// TODO implement, but not fail for now
+}
+
+SEXP R_do_slot(SEXP obj, SEXP name) {
+	return unimplemented("R_do_slot");
+}
+
+SEXP R_do_slot_assign(SEXP obj, SEXP name, SEXP value) {
+	return unimplemented("R_do_slot_assign");
+}
+
+int R_has_slot(SEXP obj, SEXP name) {
+	return (int) unimplemented("R_has_slot");
+}
+
+SEXP R_do_MAKE_CLASS(const char *what) {
+	return unimplemented("R_do_MAKE_CLASS");
+}
+
+SEXP R_getClassDef (const char *what) {
+	return unimplemented("R_getClassDef");
+}
+
+SEXP R_do_new_object(SEXP class_def) {
+	return unimplemented("R_do_new_object");
+}
+
+int R_check_class_and_super(SEXP x, const char **valid, SEXP rho) {
+	return (int) unimplemented("R_check_class_and_super");
+}
+
+int R_check_class_etc (SEXP x, const char **valid) {
+	return (int) unimplemented("R_check_class_etc");
+}
+
+SEXP R_PreserveObject(SEXP x) {
+	return unimplemented("R_PreserveObject");
+}
+
+void R_ReleaseObject(SEXP x) {
+	unimplemented("R_ReleaseObject");
+}
+
+Rboolean R_compute_identical(SEXP x, SEXP y, int flags) {
+	return (Rboolean) unimplemented("R_compute_identical");
+}
+
+void Rf_copyListMatrix(SEXP s, SEXP t, Rboolean byrow) {
+	unimplemented("Rf_copyListMatrix");
+}
+
+void Rf_copyMatrix(SEXP s, SEXP t, Rboolean byrow) {
+	unimplemented("Rf_copyMatrix");
+}
diff --git a/com.oracle.truffle.r.native/fficall/src/truffle/caccess.c b/com.oracle.truffle.r.native/fficall/src/truffle/caccess.c
new file mode 100644
index 0000000000000000000000000000000000000000..d07c61c716cf948d2b91d97027a2aa67c0e4b9cc
--- /dev/null
+++ b/com.oracle.truffle.r.native/fficall/src/truffle/caccess.c
@@ -0,0 +1,38 @@
+/*
+ * Copyright (c) 2016, 2016, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+int caccess_read_pointer_int(int *address) {
+	return *address;
+}
+
+double caccess_read_pointer_double(double *address) {
+	return *address;
+}
+
+int caccess_read_array_int(int *address, int index) {
+	return address[index];
+}
+
+double caccess_read_array_double(double *address, int index) {
+	return address[index];
+}
diff --git a/com.oracle.truffle.r.native/fficall/src/truffle/llvm_dummy.c b/com.oracle.truffle.r.native/fficall/src/truffle/llvm_dummy.c
new file mode 100644
index 0000000000000000000000000000000000000000..f786ab945c7932692e6fbecf8c98b9e0b58bac95
--- /dev/null
+++ b/com.oracle.truffle.r.native/fficall/src/truffle/llvm_dummy.c
@@ -0,0 +1,24 @@
+/*
+ * Copyright (c) 2014, 2016, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please 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 dummy file that is compiled (by fastr-cc) in place of any actual .c file in this directory.
+// This allows the IR for the actual .c file to be merged with the empty .o for llvm_dummy.
diff --git a/com.oracle.truffle.r.native/fficall/src/truffle/llvm_dummy.f b/com.oracle.truffle.r.native/fficall/src/truffle/llvm_dummy.f
new file mode 100644
index 0000000000000000000000000000000000000000..6c4e6cee29e0ca31cc15e3c1429d33061508786a
--- /dev/null
+++ b/com.oracle.truffle.r.native/fficall/src/truffle/llvm_dummy.f
@@ -0,0 +1,24 @@
+/*
+ * Copyright (c) 2014, 2016, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please 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 dummy file that is compiled (by fastr-fc) in place of any actual .f file in this directory.
+// This allows the IR for the actual .f file to be merged with the empty .o for llvm_dummy.
diff --git a/com.oracle.truffle.r.native/fficall/src/truffle/rffiutils.c b/com.oracle.truffle.r.native/fficall/src/truffle/rffiutils.c
new file mode 100644
index 0000000000000000000000000000000000000000..82a74a54059453e7fc5731fc9c429b7a8f3949c4
--- /dev/null
+++ b/com.oracle.truffle.r.native/fficall/src/truffle/rffiutils.c
@@ -0,0 +1,32 @@
+/*
+ * Copyright (c) 2016, 2016, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+#include <rffiutils.h>
+
+SEXP unimplemented(char *name) {
+	printf("unimplemented %s\n", name);
+	void *nameString = truffle_read_string(name);
+	void *obj = truffle_import_cached("_fastr_rffi_call");
+	void *result = truffle_invoke(obj, "unimplemented", nameString);
+	return result;
+}
+
diff --git a/com.oracle.truffle.r.native/fficall/src/truffle/rffiutils.h b/com.oracle.truffle.r.native/fficall/src/truffle/rffiutils.h
new file mode 100644
index 0000000000000000000000000000000000000000..d4a21793b398c4e34ea2c64f83deac513ec88ba4
--- /dev/null
+++ b/com.oracle.truffle.r.native/fficall/src/truffle/rffiutils.h
@@ -0,0 +1,36 @@
+/*
+ * Copyright (c) 2015, 2016, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+#ifndef RFFIUTILS_H
+#define RFFIUTILS_H
+
+#include <stdlib.h>
+#include <string.h>
+#include <limits.h>
+#include <Rinternals.h>
+#include <truffle.h>
+
+#define IMPORT_CALLHELPER() void *obj = truffle_import_cached("_fastr_rffi_callhelper")
+
+SEXP unimplemented(char *name);
+
+#endif /* RFFIUTILS_H */
diff --git a/com.oracle.truffle.r.native/fficall/src/truffle/variables.c b/com.oracle.truffle.r.native/fficall/src/truffle/variables.c
new file mode 100644
index 0000000000000000000000000000000000000000..a9944e5183845b3407a18815dc52638b53caa09f
--- /dev/null
+++ b/com.oracle.truffle.r.native/fficall/src/truffle/variables.c
@@ -0,0 +1,130 @@
+/*
+ * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+#include <rffiutils.h>
+#include <variable_defs.h>
+
+// R_GlobalEnv et al are not a variables in FASTR as they are RContext specific
+SEXP FASTR_GlobalEnv() {
+	IMPORT_CALLHELPER();
+	return truffle_invoke(obj, "R_GlobalEnv");
+}
+
+SEXP FASTR_BaseEnv() {
+	IMPORT_CALLHELPER();
+	return truffle_invoke(obj, "R_BaseEnv");
+}
+
+SEXP FASTR_BaseNamespace() {
+	IMPORT_CALLHELPER();
+	return truffle_invoke(obj, "R_BaseNamespace");
+}
+
+SEXP FASTR_NamespaceRegistry() {
+	IMPORT_CALLHELPER();
+	return truffle_invoke(obj, "R_NamespaceRegistry");
+}
+
+Rboolean FASTR_IsInteractive() {
+	IMPORT_CALLHELPER();
+	return (Rboolean) truffle_invoke_i(obj, "isInteractive");
+}
+
+char *FASTR_R_Home() {
+	IMPORT_CALLHELPER();
+	return (char *) truffle_invoke(obj, "R_Home");
+}
+
+SEXP FASTR_R_NilValue() {
+	IMPORT_CALLHELPER();
+	return truffle_invoke(obj, "R_NilValue");
+
+}
+
+SEXP FASTR_R_UnboundValue() {
+	IMPORT_CALLHELPER();
+	return truffle_invoke(obj, "R_UnboundValue");
+}
+
+void Call_initvar_obj(int index, void* value) {
+	/*
+	switch (index) {
+    case R_Home_x: R_Home = (char *) value; break;
+    case R_TempDir_x: R_TempDir = value; break;
+    case R_NilValue_x: R_NilValue = value; break;
+    case R_UnboundValue_x: R_UnboundValue = value; break;
+    case R_MissingArg_x: R_MissingArg = value; break;
+    case R_Srcref_x: R_Srcref = value; break;
+    case R_Bracket2Symbol_x: R_Bracket2Symbol = value; break;
+    case R_BracketSymbol_x: R_BracketSymbol = value; break;
+    case R_BraceSymbol_x: R_BraceSymbol = value; break;
+    case R_ClassSymbol_x: R_ClassSymbol = value; break;
+    case R_DeviceSymbol_x: R_DeviceSymbol = value; break;
+    case R_DevicesSymbol_x: R_DevicesSymbol = value; break;
+    case R_DimNamesSymbol_x: R_DimNamesSymbol = value; break;
+    case R_DimSymbol_x: R_DimSymbol = value; break;
+    case R_DollarSymbol_x: R_DollarSymbol = value; break;
+    case R_DotsSymbol_x: R_DotsSymbol = value; break;
+    case R_DropSymbol_x: R_DropSymbol = value; break;
+    case R_LastvalueSymbol_x: R_LastvalueSymbol = value; break;
+    case R_LevelsSymbol_x: R_LevelsSymbol = value; break;
+    case R_ModeSymbol_x: R_ModeSymbol = value; break;
+    case R_NameSymbol_x: R_NameSymbol = value; break;
+    case R_NamesSymbol_x: R_NamesSymbol = value; break;
+    case R_NaRmSymbol_x: R_NaRmSymbol = value; break;
+    case R_PackageSymbol_x: R_PackageSymbol = value; break;
+    case R_QuoteSymbol_x: R_QuoteSymbol = value; break;
+    case R_RowNamesSymbol_x: R_RowNamesSymbol = value; break;
+    case R_SeedsSymbol_x: R_SeedsSymbol = value; break;
+    case R_SourceSymbol_x: R_SourceSymbol = value; break;
+    case R_TspSymbol_x: R_TspSymbol = value; break;
+    case R_dot_defined_x: R_dot_defined = value; break;
+    case R_dot_Method_x: R_dot_Method = value; break;
+    case R_dot_target_x: R_dot_target = value; break;
+    case R_SrcrefSymbol_x: R_SrcrefSymbol = value; break;
+    case R_SrcfileSymbol_x: R_SrcfileSymbol = value; break;
+    case R_NaString_x: R_NaString = value; break;
+    case R_NaInt_x: R_NaInt = (int) value; break;
+    case R_BlankString_x: R_BlankString = value; break;
+    case R_TrueValue_x: R_TrueValue = value; break;
+    case R_FalseValue_x: R_FalseValue = value; break;
+    case R_LogicalNAValue_x: R_LogicalNAValue = value; break;
+	}
+	*/
+}
+
+void Call_initvar_double(int index, double value) {
+	switch (index) {
+    case R_NaN_x: R_NaN = value; break;
+	}
+}
+
+void Call_initvar_int(int index, int value) {
+	switch (index) {
+    case R_NaInt_x: R_NaInt = value; break;
+    case R_PosInf_x: R_PosInf = value; break;
+    case R_NegInf_x: R_NegInf = value; break;
+    case R_NaReal_x: R_NaReal = value; break;
+	}
+}
+
+
diff --git a/com.oracle.truffle.r.native/fficall/src/variable_defs/variable_defs.h b/com.oracle.truffle.r.native/fficall/src/variable_defs/variable_defs.h
index 01f2643b7dd05d124e0cfd40815233163a5ee0d1..b3c3831a5acd1392c93c3e207ebdd30ea9d16238 100644
--- a/com.oracle.truffle.r.native/fficall/src/variable_defs/variable_defs.h
+++ b/com.oracle.truffle.r.native/fficall/src/variable_defs/variable_defs.h
@@ -101,3 +101,54 @@ int max_contour_segments = 25000;
 
 static InputHandler BasicInputHandler = {2, -1, NULL};
 InputHandler *R_InputHandlers = &BasicInputHandler;
+
+// ordinal numbers of the RVariables enum
+#define R_Home_x 0
+#define R_TempDir_x 1
+#define R_NilValue_x 2
+#define R_UnboundValue_x 3
+#define R_MissingArg_x 4
+#define R_GlobalEnv_x 5
+#define R_EmptyEnv_x 6
+#define R_BaseEnv_x 7
+#define R_BaseNamespace_x 8
+#define R_NamespaceRegistry_x 9
+#define R_Srcref_x 10
+#define R_Bracket2Symbol_x 11
+#define R_BracketSymbol_x 12
+#define R_BraceSymbol_x 13
+#define R_ClassSymbol_x 14
+#define R_DeviceSymbol_x 15
+#define R_DevicesSymbol_x 16
+#define R_DimNamesSymbol_x 17
+#define R_DimSymbol_x 18
+#define R_DollarSymbol_x 19
+#define R_DotsSymbol_x 20
+#define R_DropSymbol_x 21
+#define R_LastvalueSymbol_x 22
+#define R_LevelsSymbol_x 23
+#define R_ModeSymbol_x 24
+#define R_NameSymbol_x 25
+#define R_NamesSymbol_x 26
+#define R_NaRmSymbol_x 27
+#define R_PackageSymbol_x 28
+#define R_QuoteSymbol_x 29
+#define R_RowNamesSymbol_x 30
+#define R_SeedsSymbol_x 31
+#define R_SourceSymbol_x 32
+#define R_TspSymbol_x 33
+#define R_dot_defined_x 34
+#define R_dot_Method_x 35
+#define R_dot_target_x 36
+#define R_SrcrefSymbol_x 37
+#define R_SrcfileSymbol_x 38
+#define R_NaString_x 39
+#define R_NaN_x 40
+#define R_PosInf_x 41
+#define R_NegInf_x 42
+#define R_NaReal_x 43
+#define R_NaInt_x 44
+#define R_BlankString_x 45
+#define R_TrueValue_x 46
+#define R_FalseValue_x 47
+#define R_LogicalNAValue_x 48
diff --git a/com.oracle.truffle.r.native/gnur/Makefile.gnur b/com.oracle.truffle.r.native/gnur/Makefile.gnur
index 29c57579c3e0d2c0f96e5eca81d56583072cf3ab..4b9f8580e4a38070be7ed61503dd8c306926ca90 100644
--- a/com.oracle.truffle.r.native/gnur/Makefile.gnur
+++ b/com.oracle.truffle.r.native/gnur/Makefile.gnur
@@ -40,11 +40,20 @@
 
 OSNAME := $(shell uname)
 
+ifdef FASTR_TRUFFLE_RFFI
+FC_DIR := $(abspath $(TOPDIR)/../mx.fastr/compilers)
+FASTR_COMPILERS := CC=$(FC_DIR)/fastr-cc FC=$(FC_DIR)/fastr-fc F77=$(FC_DIR)/fastr-fc CXX=$(FC_DIR)/fastr-c++ CXXCPP=$(FC_DIR)/fastr-cpp OBJC=$(FC_DIR)/fastr-cc
+endif
+
+ifndef FASTR_TRUFFLE_RFFI
+# LLVM text parser and -g don't get on
 OPT_FLAGS := -g -O2
+OPT_FLAGS := -O2
 
 CFLAGS := $(OPT_FLAGS)
 CPPFLAGS := $(OPT_FLAGS)
 CXXFLAGS := $(OPT_FLAGS)
+endif
 
 ifeq ($(OSNAME), Linux)
   FORCE_PIC := true
@@ -60,6 +69,7 @@ all: Makefile $(GNUR_HOME) iconv config build
 $(GNUR_HOME): 
 	tar xf $(TOPDIR)/../libdownloads/R-$(R_VERSION).tar.gz
 
+
 # After this platform check, GNUR_CONFIG_FLAGS must be set
 ifeq ($(OSNAME), SunOS)
 #
@@ -119,6 +129,9 @@ ifneq ($(PKG_LDFLAGS_OVERRIDE),)
         GNUR_CONFIG_FLAGS := $(GNUR_CONFIG_FLAGS) LDFLAGS=$(PKG_LDFLAGS_OVERRIDE)
 endif
 
+# setup for LLVM (if enabled)
+GNUR_CONFIG_FLAGS := $(GNUR_CONFIG_FLAGS) FFLAGS=-O2 $(FASTR_COMPILERS)
+
 endif
 # End of platform check
 
@@ -140,7 +153,7 @@ RECPKGS := "--without-recommended-packages"
 endif
 
 $(GNUR_HOME)/Makefile:
-	(cd $(GNUR_HOME); ./configure --with-x=no $(RECPKGS) --enable-memory-profiling $(GNUR_CONFIG_FLAGS) > gnur_configure.log 2>&1)
+	(cd $(GNUR_HOME); ./configure --with-x=no --with-aqua=no $(RECPKGS) --enable-memory-profiling $(GNUR_CONFIG_FLAGS) > gnur_configure.log 2>&1)
 
 build: $(GNUR_HOME)/bin/R
 
diff --git a/com.oracle.truffle.r.native/gnur/README b/com.oracle.truffle.r.native/gnur/README
deleted file mode 100644
index e241ed42ceba7ca9272292e5d68eb7fe3c277c26..0000000000000000000000000000000000000000
--- a/com.oracle.truffle.r.native/gnur/README
+++ /dev/null
@@ -1,6 +0,0 @@
-This is a multi-step process to build GnuR in such a way that FASTR can use some of the libraries.
-After building GnuR we extract configuration information for use in building packages in the FastR environment.
-This goes into the file platform.mk, which is included in the Makefile's for the standard packages built for FastR.
-The main change is to define the symbol FASTR to ensure that some important modifications to Rinternals.h are made
-(e.g. changing an SEXP to a JNI jobject).
-
diff --git a/com.oracle.truffle.r.native/include/README b/com.oracle.truffle.r.native/include/README
deleted file mode 100644
index 86972bd087a49a82162f5e7c053aed9c5fb127e8..0000000000000000000000000000000000000000
--- a/com.oracle.truffle.r.native/include/README
+++ /dev/null
@@ -1,5 +0,0 @@
-The header files that are included when compiling the code of native packages in the FastR environment.
-
-The starting position is that these files are identical to those in GnuR and that the FastR implementation
-differences are entirely encapsulated in the method implementations in the fficall library. It is TBD whether
-this can be completely transparent but,if not, the goal would be for minimal changes to the standard header files.
diff --git a/com.oracle.truffle.r.native/include/ed_Rinterface_interactive b/com.oracle.truffle.r.native/include/ed_Rinterface_interactive
index 48066ad11ff1bb4db62720f691a37c8be9983563..d226ba210788f9c015c03c6a495fd8c49b120d97 100644
--- a/com.oracle.truffle.r.native/include/ed_Rinterface_interactive
+++ b/com.oracle.truffle.r.native/include/ed_Rinterface_interactive
@@ -9,4 +9,15 @@ LibExtern Rboolean FASTR_Interactive();
 a
 #endif
 .
+/R_Home;/
+i
+#ifdef FASTR
+LibExtern char* FASTR_R_Home();
+#define R_Home FASTR_R_Home()
+#else
+.
++1
+a
+#endif
+.
 w Rinterface.h
diff --git a/com.oracle.truffle.r.native/include/ed_Rinternals b/com.oracle.truffle.r.native/include/ed_Rinternals
index c4022028d1c73d0e38c35c555af449a8030827ee..11d0c1e55752a00ed78095033e28a3e1c6f7943a 100644
--- a/com.oracle.truffle.r.native/include/ed_Rinternals
+++ b/com.oracle.truffle.r.native/include/ed_Rinternals
@@ -68,6 +68,28 @@ LibExtern SEXP FASTR_NamespaceRegistry();
 a
 #endif
 .
+/R_NilValue;/
+i
+#ifdef FASTR
+LibExtern SEXP FASTR_R_NilValue();
+#define R_NilValue FASTR_R_NilValue()
+#else
+.
++1
+a
+#endif
+.
+/R_UnboundValue;/
+i
+#ifdef FASTR
+LibExtern SEXP FASTR_R_UnboundValue();
+#define R_UnboundValue FASTR_R_UnboundValue()
+#else
+.
++1
+a
+#endif
+.
 /R_PreserveObject/
 i
 #ifdef FASTR
diff --git a/com.oracle.truffle.r.native/library/README b/com.oracle.truffle.r.native/library/README
deleted file mode 100644
index 3b933fbd7d144153eaf7144170c4640b2ab9bd43..0000000000000000000000000000000000000000
--- a/com.oracle.truffle.r.native/library/README
+++ /dev/null
@@ -1,14 +0,0 @@
-This directory tree contains the default packages for FastR. Each package directory contains a '.gz' file that was
-created from the corresponding GnuR 'library' directory, plus necessary C source and header files, most notably 'init.c',
-also copied from GnuR. Since these files reference functions in the GnuR implementation, 'init.c' is recompiled
-in the FastR environment and the resulting '.so' replaces the one from the '.gz' file in the FastR 'library' directory.
-Absolutely minimal changes are made to the C source, typically just to define (as empty functions), rather than reference,
-the C functions that are passed to R_registerRoutines. This step is still necesssary in FastR as it causes R symbols that are'
-referenced in the R package code to become defined.
-
-Note that 'datasets' and 'fastr' don't actually have any native code, but it is convenient to store them here. Note also that
-'fastr', obviously, does not originate from GnuR, so its build process is completely different.
-
-Given that we only support MacOS/Linux, it is expedient to just store the tar'ed content of the GnuR library directories
-for those targets as 'source' files in the distribution. In time, when FastR can create packages directly, the build will
-change to work that way.
diff --git a/com.oracle.truffle.r.native/library/grDevices/Makefile b/com.oracle.truffle.r.native/library/grDevices/Makefile
index 9c94eef469463a28855f2c0c929dc9263f1e70a3..50e82ab7afb18c63038688fb52cea9c863fade96 100644
--- a/com.oracle.truffle.r.native/library/grDevices/Makefile
+++ b/com.oracle.truffle.r.native/library/grDevices/Makefile
@@ -1,5 +1,5 @@
 #
-# Copyright (c) 2014, 2015, Oracle and/or its affiliates. All rights reserved.
+# Copyright (c) 2014, 2016, Oracle and/or its affiliates. All rights reserved.
 # DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
 #
 # This code is free software; you can redistribute it and/or modify it
@@ -41,7 +41,9 @@ GNUR_C_SOURCES := axis_scales.c chull.c colors.c devCairo.c devPS.c devPicTeX.c
                 devices.c init.c stubs.c
 
 ifeq ($(OS_NAME), Darwin)
-GNUR_C_SOURCES := $(GNUR_C_SOURCES) qdBitmap.c qdPDF.c
+ifneq ($(shell grep HAVE_AQUA $(GNUR_HOME)/config.log),)
+  GNUR_C_SOURCES := $(GNUR_C_SOURCES) qdBitmap.c qdPDF.c
+endif
 endif
 
 GNUR_C_OBJECTS := $(addprefix $(OBJ)/, $(GNUR_C_SOURCES:.c=.o))
diff --git a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/AsVector.java b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/AsVector.java
index 92d043c445615d2a431604f7e0f7f12b965093ca..6f3c3bc9c082d8bd0b8362e9ead3982deed14382 100644
--- a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/AsVector.java
+++ b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/AsVector.java
@@ -41,10 +41,11 @@ import com.oracle.truffle.r.nodes.builtin.CastBuilder;
 import com.oracle.truffle.r.nodes.builtin.RBuiltinNode;
 import com.oracle.truffle.r.nodes.builtin.base.AsVectorNodeGen.AsVectorInternalNodeGen;
 import com.oracle.truffle.r.nodes.builtin.base.AsVectorNodeGen.AsVectorInternalNodeGen.CastPairListNodeGen;
+import com.oracle.truffle.r.nodes.function.CallMatcherNode;
 import com.oracle.truffle.r.nodes.function.ClassHierarchyNode;
 import com.oracle.truffle.r.nodes.function.ClassHierarchyNodeGen;
 import com.oracle.truffle.r.nodes.function.S3FunctionLookupNode;
-import com.oracle.truffle.r.nodes.function.UseMethodInternalNode;
+import com.oracle.truffle.r.nodes.function.S3FunctionLookupNode.Result;
 import com.oracle.truffle.r.nodes.unary.CastComplexNode;
 import com.oracle.truffle.r.nodes.unary.CastDoubleNode;
 import com.oracle.truffle.r.nodes.unary.CastExpressionNode;
@@ -77,7 +78,9 @@ public abstract class AsVector extends RBuiltinNode {
 
     @Child private AsVectorInternal internal = AsVectorInternalNodeGen.create();
     @Child private ClassHierarchyNode classHierarchy = ClassHierarchyNodeGen.create(false, false);
-    @Child private UseMethodInternalNode useMethod;
+
+    @Child private S3FunctionLookupNode lookup;
+    @Child private CallMatcherNode callMatcher;
 
     private final ConditionProfile hasClassProfile = ConditionProfile.createBinaryProfile();
 
@@ -98,16 +101,19 @@ public abstract class AsVector extends RBuiltinNode {
         // However, removing it causes unit test failures
         RStringVector clazz = classHierarchy.execute(x);
         if (hasClassProfile.profile(clazz != null)) {
-            if (useMethod == null) {
-                // Note: this dispatch takes care of factor, because there is as.vector.factor
-                // specialization in R
+            // Note: this dispatch takes care of factor, because there is as.vector.factor
+            // specialization in R
+            if (lookup == null) {
                 CompilerDirectives.transferToInterpreterAndInvalidate();
-                useMethod = insert(new UseMethodInternalNode("as.vector", SIGNATURE, false));
+                lookup = insert(S3FunctionLookupNode.create(false, false));
             }
-            try {
-                return useMethod.execute(frame, clazz, new Object[]{x, mode});
-            } catch (S3FunctionLookupNode.NoGenericMethodException e) {
-                // fallthrough
+            Result lookupResult = lookup.execute(frame, "as.vector", clazz, null, frame.materialize(), null);
+            if (lookupResult != null) {
+                if (callMatcher == null) {
+                    CompilerDirectives.transferToInterpreterAndInvalidate();
+                    callMatcher = insert(CallMatcherNode.create(false));
+                }
+                return callMatcher.execute(frame, SIGNATURE, new Object[]{x, mode}, lookupResult.function, lookupResult.targetFunctionName, lookupResult.createS3Args(frame));
             }
         }
         return internal.execute(x, mode);
diff --git a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/Attr.java b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/Attr.java
index 10853a996c8aee8f4c672122aeb90f4cee0f4ebd..0329bf95e8ab9c10a0f8684e6eadb19e24095382 100644
--- a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/Attr.java
+++ b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/Attr.java
@@ -28,8 +28,6 @@ import static com.oracle.truffle.r.nodes.builtin.CastBuilder.Predef.toBoolean;
 import static com.oracle.truffle.r.runtime.builtins.RBehavior.PURE;
 import static com.oracle.truffle.r.runtime.builtins.RBuiltinKind.PRIMITIVE;
 
-import com.oracle.truffle.api.CompilerDirectives;
-import com.oracle.truffle.api.CompilerDirectives.CompilationFinal;
 import com.oracle.truffle.api.CompilerDirectives.TruffleBoundary;
 import com.oracle.truffle.api.dsl.Cached;
 import com.oracle.truffle.api.dsl.Fallback;
@@ -40,16 +38,16 @@ import com.oracle.truffle.api.profiles.ConditionProfile;
 import com.oracle.truffle.r.nodes.attributes.GetAttributeNode;
 import com.oracle.truffle.r.nodes.attributes.IterableAttributeNode;
 import com.oracle.truffle.r.nodes.attributes.SpecialAttributesFunctions.GetRowNamesAttributeNode;
-import com.oracle.truffle.r.nodes.attributes.UpdateSharedAttributeNode;
 import com.oracle.truffle.r.nodes.builtin.CastBuilder;
 import com.oracle.truffle.r.nodes.builtin.RBuiltinNode;
+import com.oracle.truffle.r.nodes.builtin.base.UpdateAttr.InternStringNode;
+import com.oracle.truffle.r.nodes.builtin.base.UpdateAttrNodeGen.InternStringNodeGen;
+import com.oracle.truffle.r.nodes.function.opt.UpdateShareableChildValueNode;
 import com.oracle.truffle.r.runtime.RError;
 import com.oracle.truffle.r.runtime.RError.Message;
 import com.oracle.truffle.r.runtime.RRuntime;
-import com.oracle.truffle.r.runtime.Utils;
 import com.oracle.truffle.r.runtime.builtins.RBuiltin;
 import com.oracle.truffle.r.runtime.data.RAttributable;
-import com.oracle.truffle.r.runtime.data.RAttributeProfiles;
 import com.oracle.truffle.r.runtime.data.RAttributesLayout;
 import com.oracle.truffle.r.runtime.data.RDataFactory;
 import com.oracle.truffle.r.runtime.data.RInteger;
@@ -65,9 +63,9 @@ public abstract class Attr extends RBuiltinNode {
     private final ConditionProfile searchPartialProfile = ConditionProfile.createBinaryProfile();
     private final BranchProfile errorProfile = BranchProfile.create();
 
-    @CompilationFinal private String cachedName = "";
-    @CompilationFinal private String cachedInternedName = "";
-    @Child private UpdateSharedAttributeNode sharedAttrUpdate = UpdateSharedAttributeNode.create();
+    @Child private UpdateShareableChildValueNode sharedAttrUpdate = UpdateShareableChildValueNode.create();
+    @Child private InternStringNode intern = InternStringNodeGen.create();
+
     @Child private GetAttributeNode attrAccess = GetAttributeNode.create();
     @Child private IterableAttributeNode iterAttrAccess = IterableAttributeNode.create();
 
@@ -84,28 +82,6 @@ public abstract class Attr extends RBuiltinNode {
         casts.arg("exact").asLogicalVector().findFirst().map(toBoolean());
     }
 
-    private String intern(String name) {
-        if (cachedName == null) {
-            // unoptimized case
-            return Utils.intern(name);
-        }
-        if (cachedName == name) {
-            // cached case
-            return cachedInternedName;
-        }
-        CompilerDirectives.transferToInterpreterAndInvalidate();
-        // Checkstyle: stop StringLiteralEquality
-        if (cachedName == "") {
-            // Checkstyle: resume StringLiteralEquality
-            cachedName = name;
-            cachedInternedName = Utils.intern(name);
-        } else {
-            cachedName = null;
-            cachedInternedName = null;
-        }
-        return Utils.intern(name);
-    }
-
     private Object searchKeyPartial(DynamicObject attributes, String name) {
         Object val = RNull.instance;
 
@@ -142,7 +118,7 @@ public abstract class Attr extends RBuiltinNode {
 
     @Specialization(guards = "!isRowNamesAttr(name)")
     protected Object attr(RAbstractContainer container, String name, boolean exact) {
-        return attrRA(container, intern(name), exact);
+        return attrRA(container, intern.execute(name), exact);
     }
 
     @Specialization(guards = "isRowNamesAttr(name)")
@@ -164,7 +140,7 @@ public abstract class Attr extends RBuiltinNode {
     @TruffleBoundary
     protected Object attr(Object object, Object name, Object exact) {
         if (object instanceof RAttributable) {
-            return attrRA((RAttributable) object, intern((String) name), (boolean) exact);
+            return attrRA((RAttributable) object, intern.execute((String) name), (boolean) exact);
         } else {
             errorProfile.enter();
             throw RError.nyi(this, "object cannot be attributed");
diff --git a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/BasePackage.java b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/BasePackage.java
index c1ccfdd06e08dda7ca09700f1f77d790a2c239fd..4ae9a98b0db49740bb9cdaf28f8b23898cac5aaf 100644
--- a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/BasePackage.java
+++ b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/BasePackage.java
@@ -67,7 +67,6 @@ import com.oracle.truffle.r.nodes.builtin.base.infix.IfBuiltinNodeGen;
 import com.oracle.truffle.r.nodes.builtin.base.infix.NextBuiltin;
 import com.oracle.truffle.r.nodes.builtin.base.infix.NextBuiltinNodeGen;
 import com.oracle.truffle.r.nodes.builtin.base.infix.ParenBuiltin;
-import com.oracle.truffle.r.nodes.builtin.base.infix.ParenBuiltinNodeGen;
 import com.oracle.truffle.r.nodes.builtin.base.infix.RepeatBuiltin;
 import com.oracle.truffle.r.nodes.builtin.base.infix.RepeatBuiltinNodeGen;
 import com.oracle.truffle.r.nodes.builtin.base.infix.Subscript;
@@ -255,6 +254,8 @@ public class BasePackage extends RBuiltinPackage {
         add(ConnectionFunctions.File.class, ConnectionFunctionsFactory.FileNodeGen::create);
         add(ConnectionFunctions.Flush.class, ConnectionFunctionsFactory.FlushNodeGen::create);
         add(ConnectionFunctions.GZFile.class, ConnectionFunctionsFactory.GZFileNodeGen::create);
+        add(ConnectionFunctions.BZFile.class, ConnectionFunctionsFactory.BZFileNodeGen::create);
+        add(ConnectionFunctions.XZFile.class, ConnectionFunctionsFactory.XZFileNodeGen::create);
         add(ConnectionFunctions.GetAllConnections.class, ConnectionFunctionsFactory.GetAllConnectionsNodeGen::create);
         add(ConnectionFunctions.GetConnection.class, ConnectionFunctionsFactory.GetConnectionNodeGen::create);
         add(ConnectionFunctions.IsOpen.class, ConnectionFunctionsFactory.IsOpenNodeGen::create);
@@ -281,6 +282,7 @@ public class BasePackage extends RBuiltinPackage {
         add(Contributors.class, ContributorsNodeGen::create);
         add(CopyDFAttr.class, CopyDFAttrNodeGen::create);
         add(Crossprod.class, CrossprodNodeGen::create);
+        add(CRC64.class, CRC64NodeGen::create);
         add(CumMax.class, CumMaxNodeGen::create);
         add(CumMin.class, CumMinNodeGen::create);
         add(CumProd.class, CumProdNodeGen::create);
@@ -358,6 +360,7 @@ public class BasePackage extends RBuiltinPackage {
         add(FastRTry.class, FastRTryNodeGen::create);
         add(FastRInspect.class, FastRInspectNodeGen::create);
         add(FastRInterop.Eval.class, FastRInteropFactory.EvalNodeGen::create);
+        add(FastRInterop.EvalFile.class, FastRInteropFactory.EvalFileNodeGen::create);
         add(FastRInterop.Export.class, FastRInteropFactory.ExportNodeGen::create);
         add(FastRInterop.HasSize.class, FastRInteropFactory.HasSizeNodeGen::create);
         add(FastRInterop.Import.class, FastRInteropFactory.ImportNodeGen::create);
@@ -667,6 +670,7 @@ public class BasePackage extends RBuiltinPackage {
         add(UpdateClass.class, UpdateClassNodeGen::create);
         add(UpdateDim.class, UpdateDimNodeGen::create);
         add(UpdateDimNames.class, UpdateDimNamesNodeGen::create);
+        add(Utf8ToInt.class, Utf8ToIntNodeGen::create);
         add(EnvFunctions.UpdateEnvironment.class, EnvFunctionsFactory.UpdateEnvironmentNodeGen::create);
         add(UpdateLength.class, UpdateLengthNodeGen::create);
         add(UpdateLevels.class, UpdateLevelsNodeGen::create);
@@ -702,7 +706,7 @@ public class BasePackage extends RBuiltinPackage {
         add(FunctionBuiltin.class, FunctionBuiltinNodeGen::create);
         add(IfBuiltin.class, IfBuiltinNodeGen::create);
         add(NextBuiltin.class, NextBuiltinNodeGen::create);
-        add(ParenBuiltin.class, ParenBuiltinNodeGen::create);
+        add(ParenBuiltin.class, ParenBuiltin::new, ParenBuiltin::special);
         add(RepeatBuiltin.class, RepeatBuiltinNodeGen::create);
         add(Tilde.class, TildeNodeGen::create);
         add(UpdateSubscript.class, UpdateSubscriptNodeGen::create, UpdateSubscript::special);
diff --git a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/Bind.java b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/Bind.java
index 0a95c508e5ae397f7717df4e96528108cb1d0c27..13294d4f362ab562c0db9a44cb1426995eaca939 100644
--- a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/Bind.java
+++ b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/Bind.java
@@ -43,8 +43,9 @@ import com.oracle.truffle.r.nodes.attributes.SpecialAttributesFunctions.SetDimAt
 import com.oracle.truffle.r.nodes.attributes.SpecialAttributesFunctions.SetDimNamesAttributeNode;
 import com.oracle.truffle.r.nodes.builtin.CastBuilder;
 import com.oracle.truffle.r.nodes.builtin.RBuiltinNode;
+import com.oracle.truffle.r.nodes.function.CallMatcherNode;
 import com.oracle.truffle.r.nodes.function.S3FunctionLookupNode;
-import com.oracle.truffle.r.nodes.function.UseMethodInternalNode;
+import com.oracle.truffle.r.nodes.function.S3FunctionLookupNode.Result;
 import com.oracle.truffle.r.nodes.helpers.InheritsCheckNode;
 import com.oracle.truffle.r.nodes.unary.CastComplexNode;
 import com.oracle.truffle.r.nodes.unary.CastDoubleNode;
@@ -97,10 +98,12 @@ public abstract class Bind extends RBaseNode {
     public abstract Object execute(VirtualFrame frame, int deparseLevel, Object[] args, RArgsValuesAndNames promiseArgs, int precedence);
 
     @Child private CastToVectorNode castVector;
-    @Child private UseMethodInternalNode dcn;
     @Child private CastLogicalNode castLogical;
     @Child private GetDimAttributeNode getDimsNode;
 
+    @Child private S3FunctionLookupNode lookup;
+    @Child private CallMatcherNode callMatcher;
+
     private final BindType type;
 
     private final ConditionProfile nullNamesProfile = ConditionProfile.createBinaryProfile();
@@ -162,15 +165,19 @@ public abstract class Bind extends RBaseNode {
 
     @Specialization(guards = {"args.length > 0", "isDataFrame(args)"})
     protected Object allDataFrame(VirtualFrame frame, int deparseLevel, @SuppressWarnings("unused") Object[] args, RArgsValuesAndNames promiseArgs, @SuppressWarnings("unused") int precedence) {
-        if (dcn == null) {
+        if (lookup == null) {
             CompilerDirectives.transferToInterpreterAndInvalidate();
-            dcn = insert(new UseMethodInternalNode(type.toString(), SIGNATURE, false));
+            lookup = insert(S3FunctionLookupNode.create(false, false));
         }
-        try {
-            return dcn.execute(frame, DATA_FRAME_CLASS, new Object[]{deparseLevel, promiseArgs});
-        } catch (S3FunctionLookupNode.NoGenericMethodException e) {
+        Result lookupResult = lookup.execute(frame, type.toString(), DATA_FRAME_CLASS, null, frame.materialize(), null);
+        if (lookupResult == null) {
             throw RInternalError.shouldNotReachHere();
         }
+        if (callMatcher == null) {
+            CompilerDirectives.transferToInterpreterAndInvalidate();
+            callMatcher = insert(CallMatcherNode.create(false));
+        }
+        return callMatcher.execute(frame, SIGNATURE, new Object[]{deparseLevel, promiseArgs}, lookupResult.function, lookupResult.targetFunctionName, lookupResult.createS3Args(frame));
     }
 
     private Object bindInternal(int deparseLevel, Object[] args, RArgsValuesAndNames promiseArgs, CastNode castNode, boolean needsVectorCast, SetDimAttributeNode setDimNode,
diff --git a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/CRC64.java b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/CRC64.java
new file mode 100644
index 0000000000000000000000000000000000000000..c492da931b26adedf73a7520833fdd76fd63ed4d
--- /dev/null
+++ b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/CRC64.java
@@ -0,0 +1,67 @@
+/*
+ * Copyright (c) 2015, 2016, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package com.oracle.truffle.r.nodes.builtin.base;
+
+import com.oracle.truffle.api.CompilerDirectives.TruffleBoundary;
+import static com.oracle.truffle.r.runtime.builtins.RBehavior.PURE;
+import static com.oracle.truffle.r.runtime.builtins.RBuiltinKind.INTERNAL;
+
+import com.oracle.truffle.api.dsl.Specialization;
+import com.oracle.truffle.r.nodes.builtin.CastBuilder;
+import static com.oracle.truffle.r.nodes.builtin.CastBuilder.Predef.stringValue;
+import com.oracle.truffle.r.nodes.builtin.RBuiltinNode;
+import com.oracle.truffle.r.runtime.RError;
+import com.oracle.truffle.r.runtime.RError.Message;
+import com.oracle.truffle.r.runtime.builtins.RBuiltin;
+import com.oracle.truffle.r.runtime.data.RDataFactory;
+import com.oracle.truffle.r.runtime.data.model.RAbstractStringVector;
+
+@RBuiltin(name = "crc64", kind = INTERNAL, parameterNames = {"x"}, behavior = PURE)
+public abstract class CRC64 extends RBuiltinNode {
+
+    @Override
+    protected void createCasts(CastBuilder casts) {
+        casts.arg("x").conf(x -> x.mustNotBeMissing(RError.SHOW_CALLER2, Message.ARGUMENTS_PASSED_INTERNAL_0_1, getRBuiltin().name())).mustNotBeNull(RError.NO_CALLER,
+                        Message.INPUT_MUST_BE_STRING).mustBe(stringValue(), RError.NO_CALLER, Message.INPUT_MUST_BE_STRING);
+    }
+
+    @Specialization
+    protected RAbstractStringVector crc64(RAbstractStringVector x) {
+        final String string = x.getDataAt(0);
+        byte[] bytes = string.getBytes();
+        bytes = crc64(bytes);
+        long l = 0;
+        for (int i = 0; i < bytes.length; i++) {
+            l += (bytes[i] & 0xffL) << (8 * i);
+        }
+        return RDataFactory.createStringVector(Long.toHexString(l));
+    }
+
+    @TruffleBoundary
+    private static byte[] crc64(byte[] bytes) {
+        org.tukaani.xz.check.CRC64 crc = new org.tukaani.xz.check.CRC64();
+        crc.update(bytes);
+        return crc.finish();
+    }
+
+}
diff --git a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/Combine.java b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/Combine.java
index 99f09dcce3d563e95b0a3292e91bb7de0395d97e..1c53a2a22f3c49d902566448a343248d18502451 100644
--- a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/Combine.java
+++ b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/Combine.java
@@ -68,7 +68,6 @@ import com.oracle.truffle.r.runtime.RError;
 import com.oracle.truffle.r.runtime.RRuntime;
 import com.oracle.truffle.r.runtime.builtins.RBuiltin;
 import com.oracle.truffle.r.runtime.data.RArgsValuesAndNames;
-import com.oracle.truffle.r.runtime.data.RAttributeProfiles;
 import com.oracle.truffle.r.runtime.data.RAttributesLayout;
 import com.oracle.truffle.r.runtime.data.RDataFactory;
 import com.oracle.truffle.r.runtime.data.RLanguage;
@@ -458,7 +457,6 @@ public abstract class Combine extends RBuiltinNode {
     @NodeChild
     protected abstract static class CombineInputCast extends RNode {
 
-        private final RAttributeProfiles attrProfiles = RAttributeProfiles.create();
         @Child private GetDimNamesAttributeNode getDimNamesNode = GetDimNamesAttributeNode.create();
         @Child private GetNamesAttributeNode getNamesNode = GetNamesAttributeNode.create();
 
diff --git a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/ConditionFunctions.java b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/ConditionFunctions.java
index 3957c5a02abfa8b64f6d1b8adc046841f4d07523..14d191a2e99094dd2e9296e8e1f546ed7a5c982d 100644
--- a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/ConditionFunctions.java
+++ b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/ConditionFunctions.java
@@ -21,9 +21,14 @@ import static com.oracle.truffle.r.runtime.builtins.RBuiltinKind.INTERNAL;
 
 import com.oracle.truffle.api.CompilerDirectives;
 import com.oracle.truffle.api.CompilerDirectives.TruffleBoundary;
+import com.oracle.truffle.api.dsl.Cached;
 import com.oracle.truffle.api.dsl.Specialization;
+import com.oracle.truffle.api.frame.FrameSlot;
+import com.oracle.truffle.api.frame.FrameSlotTypeException;
+import com.oracle.truffle.api.frame.VirtualFrame;
 import com.oracle.truffle.r.nodes.builtin.CastBuilder;
 import com.oracle.truffle.r.nodes.builtin.RBuiltinNode;
+import com.oracle.truffle.r.nodes.function.FunctionDefinitionNode;
 import com.oracle.truffle.r.nodes.function.PromiseHelperNode;
 import com.oracle.truffle.r.runtime.RError;
 import com.oracle.truffle.r.runtime.RErrorHandling;
@@ -67,15 +72,31 @@ public class ConditionFunctions {
             return getHandlerStack();
         }
 
+        protected FrameSlot createHandlerFrameSlot(VirtualFrame frame) {
+            return ((FunctionDefinitionNode) getRootNode()).getHandlerFrameSlot(frame);
+        }
+
         @Specialization
-        @TruffleBoundary
-        protected Object addCondHands(RAbstractStringVector classes, RList handlers, REnvironment parentEnv, Object target, byte calling) {
+        protected Object addCondHands(VirtualFrame frame, RAbstractStringVector classes, RList handlers, REnvironment parentEnv, Object target, byte calling,
+                        @Cached("createHandlerFrameSlot(frame)") FrameSlot handlerFrameSlot) {
             if (classes.getLength() != handlers.getLength()) {
+                CompilerDirectives.transferToInterpreter();
                 throw RError.error(this, RError.Message.BAD_HANDLER_DATA);
             }
-            return RErrorHandling.createHandlers(classes, handlers, parentEnv, target, calling);
+            try {
+                if (!frame.isObject(handlerFrameSlot) || frame.getObject(handlerFrameSlot) == null) {
+                    frame.setObject(handlerFrameSlot, RErrorHandling.getHandlerStack());
+                }
+            } catch (FrameSlotTypeException e) {
+                throw RInternalError.shouldNotReachHere();
+            }
+            return createHandlers(classes, handlers, parentEnv, target, calling);
         }
 
+        @TruffleBoundary
+        private static Object createHandlers(RAbstractStringVector classes, RList handlers, REnvironment parentEnv, Object target, byte calling) {
+            return RErrorHandling.createHandlers(classes, handlers, parentEnv, target, calling);
+        }
     }
 
     @RBuiltin(name = ".resetCondHands", visibility = OFF, kind = INTERNAL, parameterNames = {"stack"}, behavior = COMPLEX)
@@ -108,9 +129,21 @@ public class ConditionFunctions {
             restart(casts);
         }
 
+        protected FrameSlot createRestartFrameSlot(VirtualFrame frame) {
+            return ((FunctionDefinitionNode) getRootNode()).getRestartFrameSlot(frame);
+        }
+
         @Specialization
-        protected Object addRestart(RList restart) {
+        protected Object addRestart(VirtualFrame frame, RList restart,
+                        @Cached("createRestartFrameSlot(frame)") FrameSlot restartFrameSlot) {
             checkLength(restart);
+            try {
+                if (!frame.isObject(restartFrameSlot) || frame.getObject(restartFrameSlot) == null) {
+                    frame.setObject(restartFrameSlot, RErrorHandling.getRestartStack());
+                }
+            } catch (FrameSlotTypeException e) {
+                throw RInternalError.shouldNotReachHere();
+            }
             RErrorHandling.addRestart(restart);
             return RNull.instance;
         }
diff --git a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/ConnectionFunctions.java b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/ConnectionFunctions.java
index df46b16704bc913cca3af30da9027533d27569f2..8c4cff9d5b23a1d7120484793d863a7fbc99dd2c 100644
--- a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/ConnectionFunctions.java
+++ b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/ConnectionFunctions.java
@@ -52,7 +52,6 @@ import java.nio.ByteOrder;
 import java.nio.DoubleBuffer;
 import java.nio.IntBuffer;
 import java.util.ArrayList;
-import java.util.zip.ZipException;
 
 import com.oracle.truffle.api.CompilerDirectives.TruffleBoundary;
 import com.oracle.truffle.api.dsl.Cached;
@@ -66,10 +65,11 @@ import com.oracle.truffle.r.runtime.RError;
 import com.oracle.truffle.r.runtime.RError.Message;
 import com.oracle.truffle.r.runtime.RInternalError;
 import com.oracle.truffle.r.runtime.RRuntime;
+import com.oracle.truffle.r.runtime.RCompression;
 import com.oracle.truffle.r.runtime.builtins.RBuiltin;
 import com.oracle.truffle.r.runtime.conn.ConnectionSupport.BaseRConnection;
 import com.oracle.truffle.r.runtime.conn.FileConnections.FileRConnection;
-import com.oracle.truffle.r.runtime.conn.GZIPConnections.GZIPRConnection;
+import com.oracle.truffle.r.runtime.conn.CompressedConnections.CompressedRConnection;
 import com.oracle.truffle.r.runtime.conn.RConnection;
 import com.oracle.truffle.r.runtime.conn.SocketConnections.RSocketConnection;
 import com.oracle.truffle.r.runtime.conn.TextConnections.TextRConnection;
@@ -225,34 +225,31 @@ public abstract class ConnectionFunctions {
 
     }
 
-    /**
-     * {@code gzfile} is very versatile (unfortunately); it can open uncompressed files, and files
-     * compressed by {@code bzip2, xz, lzma}. Currently we only support {@code gzip} and
-     * uncompressed.
+    /*
+     * In GNUR R {@code gzfile, bzfile, xzfile} are very versatile on input; they can open
+     * uncompressed files, and files compressed by {@code bzip2, xz, lzma}.
      */
-    @RBuiltin(name = "gzfile", kind = INTERNAL, parameterNames = {"description", "open", "encoding", "compression"}, behavior = IO)
-    public abstract static class GZFile extends RBuiltinNode {
+
+    public abstract static class ZZFileAdapter extends RBuiltinNode {
+        private final RCompression.Type cType;
+
+        protected ZZFileAdapter(RCompression.Type cType) {
+            this.cType = cType;
+        }
+
         @Override
         protected void createCasts(CastBuilder casts) {
             Casts.description(casts);
             Casts.open(casts);
             Casts.encoding(casts);
-            casts.arg("compression").asIntegerVector().findFirst().notNA().mustBe(gte(0).and(lte(9)));
+            casts.arg("compression").asIntegerVector().findFirst().notNA().mustBe(gte(cType == RCompression.Type.XZ ? -9 : 0).and(lte(9)));
         }
 
         @Specialization
         @TruffleBoundary
-        @SuppressWarnings("unused")
-        protected RAbstractIntVector gzFile(RAbstractStringVector description, String open, RAbstractStringVector encoding, int compression) {
+        protected RAbstractIntVector zzFile(RAbstractStringVector description, String open, String encoding, int compression) {
             try {
-                return new GZIPRConnection(description.getDataAt(0), open).asVector();
-            } catch (ZipException ex) {
-                // wasn't a gzip file, try uncompressed text
-                try {
-                    return new FileRConnection(description.getDataAt(0), "r").asVector();
-                } catch (IOException ex1) {
-                    throw reportError(description.getDataAt(0), ex1);
-                }
+                return new CompressedRConnection(description.getDataAt(0), open, cType, encoding, compression).asVector();
             } catch (IOException ex) {
                 throw reportError(description.getDataAt(0), ex);
             }
@@ -264,6 +261,30 @@ public abstract class ConnectionFunctions {
         }
     }
 
+    @RBuiltin(name = "gzfile", kind = INTERNAL, parameterNames = {"description", "open", "encoding", "compression"}, behavior = IO)
+    public abstract static class GZFile extends ZZFileAdapter {
+        protected GZFile() {
+            super(RCompression.Type.GZIP);
+        }
+
+    }
+
+    @RBuiltin(name = "bzfile", kind = INTERNAL, parameterNames = {"description", "open", "encoding", "compression"}, behavior = IO)
+    public abstract static class BZFile extends ZZFileAdapter {
+        protected BZFile() {
+            super(RCompression.Type.BZIP2);
+        }
+
+    }
+
+    @RBuiltin(name = "xzfile", kind = INTERNAL, parameterNames = {"description", "open", "encoding", "compression"}, behavior = IO)
+    public abstract static class XZFile extends ZZFileAdapter {
+        protected XZFile() {
+            super(RCompression.Type.XZ);
+        }
+
+    }
+
     @RBuiltin(name = "textConnection", kind = INTERNAL, parameterNames = {"description", "text", "open", "env", "encoding"}, behavior = IO)
     public abstract static class TextConnection extends RBuiltinNode {
         @Override
diff --git a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/DoCall.java b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/DoCall.java
index dbcf174805a15697847c63c09643e27572a98e02..746a892680cd7f6674d955dd2c501a1d1b290e4c 100644
--- a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/DoCall.java
+++ b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/DoCall.java
@@ -24,12 +24,13 @@ package com.oracle.truffle.r.nodes.builtin.base;
 
 import static com.oracle.truffle.r.nodes.builtin.CastBuilder.Predef.instanceOf;
 import static com.oracle.truffle.r.nodes.builtin.CastBuilder.Predef.stringValue;
+import static com.oracle.truffle.r.nodes.builtin.CastBuilder.Predef.toBoolean;
 import static com.oracle.truffle.r.runtime.RVisibility.CUSTOM;
 import static com.oracle.truffle.r.runtime.builtins.RBehavior.COMPLEX;
-import static com.oracle.truffle.r.runtime.builtins.RBuiltinKind.INTERNAL;
 
 import com.oracle.truffle.api.CompilerDirectives;
 import com.oracle.truffle.api.CompilerDirectives.TruffleBoundary;
+import com.oracle.truffle.api.dsl.Cached;
 import com.oracle.truffle.api.dsl.Specialization;
 import com.oracle.truffle.api.frame.FrameSlot;
 import com.oracle.truffle.api.frame.MaterializedFrame;
@@ -37,9 +38,11 @@ import com.oracle.truffle.api.frame.VirtualFrame;
 import com.oracle.truffle.api.profiles.BranchProfile;
 import com.oracle.truffle.r.nodes.RASTUtils;
 import com.oracle.truffle.r.nodes.access.FrameSlotNode;
+import com.oracle.truffle.r.nodes.access.variables.ReadVariableNode;
 import com.oracle.truffle.r.nodes.attributes.SpecialAttributesFunctions.GetNamesAttributeNode;
 import com.oracle.truffle.r.nodes.builtin.CastBuilder;
 import com.oracle.truffle.r.nodes.builtin.RBuiltinNode;
+import com.oracle.truffle.r.nodes.builtin.base.GetFunctions.Get;
 import com.oracle.truffle.r.nodes.builtin.base.GetFunctionsFactory.GetNodeGen;
 import com.oracle.truffle.r.nodes.function.GetCallerFrameNode;
 import com.oracle.truffle.r.nodes.function.RCallBaseNode;
@@ -47,8 +50,10 @@ import com.oracle.truffle.r.nodes.function.RCallNode;
 import com.oracle.truffle.r.runtime.ArgumentsSignature;
 import com.oracle.truffle.r.runtime.RError;
 import com.oracle.truffle.r.runtime.RError.Message;
+import com.oracle.truffle.r.runtime.RRuntime;
 import com.oracle.truffle.r.runtime.RType;
 import com.oracle.truffle.r.runtime.builtins.RBuiltin;
+import com.oracle.truffle.r.runtime.builtins.RBuiltinKind;
 import com.oracle.truffle.r.runtime.context.RContext;
 import com.oracle.truffle.r.runtime.data.RArgsValuesAndNames;
 import com.oracle.truffle.r.runtime.data.RDataFactory;
@@ -56,21 +61,22 @@ import com.oracle.truffle.r.runtime.data.REmpty;
 import com.oracle.truffle.r.runtime.data.RFunction;
 import com.oracle.truffle.r.runtime.data.RLanguage;
 import com.oracle.truffle.r.runtime.data.RList;
+import com.oracle.truffle.r.runtime.data.RMissing;
 import com.oracle.truffle.r.runtime.data.RPromise;
 import com.oracle.truffle.r.runtime.data.RPromise.Closure;
 import com.oracle.truffle.r.runtime.data.RPromise.PromiseState;
 import com.oracle.truffle.r.runtime.data.RStringVector;
 import com.oracle.truffle.r.runtime.data.RSymbol;
 import com.oracle.truffle.r.runtime.data.model.RAbstractListVector;
+import com.oracle.truffle.r.runtime.data.model.RAbstractStringVector;
 import com.oracle.truffle.r.runtime.env.REnvironment;
 import com.oracle.truffle.r.runtime.nodes.InternalRSyntaxNodeChildren;
 import com.oracle.truffle.r.runtime.nodes.RSyntaxNode;
 
 // TODO Implement completely, this is a simple implementation that works when the envir argument is ignored
-@RBuiltin(name = "do.call", visibility = CUSTOM, kind = INTERNAL, parameterNames = {"what", "args", "envir"}, behavior = COMPLEX)
+@RBuiltin(name = "do.call", visibility = CUSTOM, kind = RBuiltinKind.SUBSTITUTE, parameterNames = {"what", "args", "quote", "envir"}, behavior = COMPLEX)
 public abstract class DoCall extends RBuiltinNode implements InternalRSyntaxNodeChildren {
 
-    @Child private GetFunctions.Get getNode;
     @Child private GetCallerFrameNode getCallerFrame;
     @Child private GetNamesAttributeNode getNamesNode = GetNamesAttributeNode.create();
 
@@ -85,30 +91,52 @@ public abstract class DoCall extends RBuiltinNode implements InternalRSyntaxNode
     protected void createCasts(CastBuilder casts) {
         casts.arg("what").defaultError(Message.MUST_BE_STRING_OR_FUNCTION, "what").mustBe(instanceOf(RFunction.class).or(stringValue()));
         casts.arg("args").mustBe(RAbstractListVector.class, Message.SECOND_ARGUMENT_LIST);
-        casts.arg("envir").mustBe(REnvironment.class, Message.MUST_BE_ENVIRON, "envir");
+        casts.arg("quote").asLogicalVector().findFirst(RRuntime.LOGICAL_FALSE).map(toBoolean());
+        casts.arg("envir").allowMissing().mustBe(REnvironment.class, Message.MUST_BE_ENVIRON, "envir");
     }
 
-    @Specialization
-    protected Object doCall(VirtualFrame frame, String what, RList argsAsList, REnvironment env) {
-        RFunction func;
-        if (getNode == null) {
-            CompilerDirectives.transferToInterpreterAndInvalidate();
-            getNode = insert(GetNodeGen.create());
+    protected static Get createGet() {
+        return GetNodeGen.create();
+    }
+
+    protected ReadVariableNode createRead(RAbstractStringVector what) {
+        if (what.getLength() != 1) {
+            CompilerDirectives.transferToInterpreter();
+            throw RError.error(this, RError.Message.MUST_BE_STRING_OR_FUNCTION, "what");
         }
-        func = (RFunction) getNode.execute(frame, what, env, RType.Function.getName(), true);
-        return doCall(frame, func, argsAsList, env);
+        return ReadVariableNode.createForcedFunctionLookup(RSyntaxNode.INTERNAL, what.getDataAt(0));
     }
 
     @Specialization
-    protected Object doCall(VirtualFrame frame, RStringVector what, RList argsAsList, REnvironment env) {
+    protected Object doCall(VirtualFrame frame, RAbstractStringVector what, RList argsAsList, boolean quote, REnvironment env,
+                    @Cached("createGet()") Get getNode) {
+        if (what.getLength() != 1) {
+            CompilerDirectives.transferToInterpreter();
+            throw RError.error(this, RError.Message.MUST_BE_STRING_OR_FUNCTION, "what");
+        }
+        RFunction func = (RFunction) getNode.execute(frame, what.getDataAt(0), env, RType.Function.getName(), true);
+        return doCall(frame, func, argsAsList, quote, env);
+    }
+
+    @Specialization(limit = "3", guards = {"what.getLength() == 1", "read.getIdentifier() == what.getDataAt(0)"})
+    protected Object doCallCached(VirtualFrame frame, @SuppressWarnings("unused") RAbstractStringVector what, RList argsAsList, boolean quote, RMissing env,
+                    @Cached("createRead(what)") ReadVariableNode read) {
+        RFunction func = (RFunction) read.execute(frame);
+        return doCall(frame, func, argsAsList, quote, env);
+    }
+
+    @Specialization(contains = "doCallCached")
+    protected Object doCall(VirtualFrame frame, RAbstractStringVector what, RList argsAsList, boolean quote, RMissing env) {
         if (what.getLength() != 1) {
+            CompilerDirectives.transferToInterpreter();
             throw RError.error(this, RError.Message.MUST_BE_STRING_OR_FUNCTION, "what");
         }
-        return doCall(frame, what.getDataAt(0), argsAsList, env);
+        RFunction func = ReadVariableNode.lookupFunction(what.getDataAt(0), frame.materialize());
+        return doCall(frame, func, argsAsList, quote, env);
     }
 
     @Specialization
-    protected Object doCall(VirtualFrame frame, RFunction func, RList argsAsList, @SuppressWarnings("unused") REnvironment env) {
+    protected Object doCall(VirtualFrame frame, RFunction func, RList argsAsList, boolean quote, @SuppressWarnings("unused") Object env) {
         /*
          * To re-create the illusion of a normal call, turn the values in argsAsList into promises.
          */
@@ -125,22 +153,21 @@ public abstract class DoCall extends RBuiltinNode implements InternalRSyntaxNode
             }
             signature = ArgumentsSignature.get(argNames);
         }
-        MaterializedFrame callerFrame = null;
-        for (int i = 0; i < argValues.length; i++) {
-            Object arg = argValues[i];
-            if (arg instanceof RLanguage) {
-                containsRLanguageProfile.enter();
-                callerFrame = getCallerFrame(frame, callerFrame);
-                RLanguage lang = (RLanguage) arg;
-                argValues[i] = createRLanguagePromise(callerFrame, lang);
-            } else if (arg instanceof RSymbol) {
-                containsRSymbolProfile.enter();
-                RSymbol symbol = (RSymbol) arg;
-                if (symbol.getName().isEmpty()) {
-                    argValues[i] = REmpty.instance;
-                } else {
-                    callerFrame = getCallerFrame(frame, callerFrame);
-                    argValues[i] = createLookupPromise(callerFrame, symbol);
+        if (!quote) {
+            for (int i = 0; i < argValues.length; i++) {
+                Object arg = argValues[i];
+                if (arg instanceof RLanguage) {
+                    containsRLanguageProfile.enter();
+                    RLanguage lang = (RLanguage) arg;
+                    argValues[i] = createRLanguagePromise(frame.materialize(), lang);
+                } else if (arg instanceof RSymbol) {
+                    containsRSymbolProfile.enter();
+                    RSymbol symbol = (RSymbol) arg;
+                    if (symbol.getName().isEmpty()) {
+                        argValues[i] = REmpty.instance;
+                    } else {
+                        argValues[i] = createLookupPromise(frame.materialize(), symbol);
+                    }
                 }
             }
         }
@@ -163,16 +190,4 @@ public abstract class DoCall extends RBuiltinNode implements InternalRSyntaxNode
     private static RPromise createRLanguagePromise(MaterializedFrame callerFrame, RLanguage lang) {
         return RDataFactory.createPromise(PromiseState.Supplied, RPromise.Closure.create(RASTUtils.cloneNode(lang.getRep())), callerFrame);
     }
-
-    private MaterializedFrame getCallerFrame(VirtualFrame frame, MaterializedFrame callerFrame) {
-        if (getCallerFrame == null) {
-            CompilerDirectives.transferToInterpreterAndInvalidate();
-            getCallerFrame = insert(new GetCallerFrameNode());
-        }
-        if (callerFrame == null) {
-            return getCallerFrame.execute(frame);
-        } else {
-            return callerFrame;
-        }
-    }
 }
diff --git a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/Drop.java b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/Drop.java
index 7104921f0dc2c92786597d31e9c707f6fadf5f1c..bb060fb21b0ac5b918907432c43338dc83c381b9 100644
--- a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/Drop.java
+++ b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/Drop.java
@@ -36,7 +36,6 @@ import com.oracle.truffle.r.nodes.attributes.SpecialAttributesFunctions.SetDimNa
 import com.oracle.truffle.r.nodes.attributes.SpecialAttributesFunctions.SetNamesAttributeNode;
 import com.oracle.truffle.r.nodes.builtin.RBuiltinNode;
 import com.oracle.truffle.r.runtime.builtins.RBuiltin;
-import com.oracle.truffle.r.runtime.data.RAttributeProfiles;
 import com.oracle.truffle.r.runtime.data.RDataFactory;
 import com.oracle.truffle.r.runtime.data.RList;
 import com.oracle.truffle.r.runtime.data.RStringVector;
@@ -47,7 +46,6 @@ import com.oracle.truffle.r.runtime.data.model.RAbstractVector;
 public abstract class Drop extends RBuiltinNode {
 
     private final ConditionProfile nullDimensions = ConditionProfile.createBinaryProfile();
-    private final RAttributeProfiles dimNamesAttrProfile = RAttributeProfiles.create();
     private final ConditionProfile resultIsVector = ConditionProfile.createBinaryProfile();
     private final ConditionProfile resultIsScalarProfile = ConditionProfile.createBinaryProfile();
     private final ConditionProfile noDimNamesProfile = ConditionProfile.createBinaryProfile();
diff --git a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/FileFunctions.java b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/FileFunctions.java
index 63d8b68047883562b4511b147b70663fb83c40ca..e6194ce93d9c6568b63a2b4d8fd126805d4eb31f 100644
--- a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/FileFunctions.java
+++ b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/FileFunctions.java
@@ -67,9 +67,7 @@ import com.oracle.truffle.r.runtime.RError.Message;
 import com.oracle.truffle.r.runtime.RInternalError;
 import com.oracle.truffle.r.runtime.RRuntime;
 import com.oracle.truffle.r.runtime.Utils;
-import com.oracle.truffle.r.runtime.builtins.RBehavior;
 import com.oracle.truffle.r.runtime.builtins.RBuiltin;
-import com.oracle.truffle.r.runtime.builtins.RBuiltinKind;
 import com.oracle.truffle.r.runtime.context.ConsoleHandler;
 import com.oracle.truffle.r.runtime.context.RContext;
 import com.oracle.truffle.r.runtime.data.RDataFactory;
@@ -1018,7 +1016,7 @@ public class FileFunctions {
         }
     }
 
-    @RBuiltin(name = "file.show", kind = RBuiltinKind.INTERNAL, parameterNames = {"files", "header", "title", "delete.file", "pager"}, behavior = RBehavior.IO)
+    @RBuiltin(name = "file.show", kind = INTERNAL, parameterNames = {"files", "header", "title", "delete.file", "pager"}, visibility = OFF, behavior = IO)
     public abstract static class FileShow extends RBuiltinNode {
 
         @Override
diff --git a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/GrepFunctions.java b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/GrepFunctions.java
index f873109da07b8215fc2cbf199541c0ec6dd8e2df..e4eabf251c08f14a3b4c68cae04097fbc6f3fcd1 100644
--- a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/GrepFunctions.java
+++ b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/GrepFunctions.java
@@ -1267,8 +1267,8 @@ public class GrepFunctions {
                 lastEndIndex = endIndex;
                 matches.add(match);
             }
-            if (lastEndOffset < data.length()) {
-                matches.add(data.substring(lastEndOffset));
+            if (lastEndIndex < data.length()) {
+                matches.add(data.substring(lastEndIndex));
             }
             String[] result = new String[matches.size()];
             matches.toArray(result);
diff --git a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/HiddenInternalFunctions.java b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/HiddenInternalFunctions.java
index d04b57fd08082c853c5738796cd4fa9a5d2f151a..7d4077d857cbb8216a7206c87de87fb8ce63885c 100644
--- a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/HiddenInternalFunctions.java
+++ b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/HiddenInternalFunctions.java
@@ -399,7 +399,7 @@ public class HiddenInternalFunctions {
                         throw RError.error(this, Message.GENERIC, "zlib compress error");
                     }
                 } else if (compression == 3) {
-                    ctype = RCompression.Type.LZMA;
+                    ctype = RCompression.Type.XZ;
                     offset = 5;
                     outLen = data.length;
                     cdata = new byte[outLen];
@@ -446,8 +446,8 @@ public class HiddenInternalFunctions {
                 byte[] ulenData = new byte[4];
                 dataLengthBuf.get(ulenData);
                 out.write(ulenData);
-                if (type == RCompression.Type.LZMA) {
-                    out.write(RCompression.Type.LZMA.typeByte);
+                if (type == RCompression.Type.XZ) {
+                    out.write(RCompression.Type.XZ.typeByte);
                 }
                 out.write(cdata);
                 return result;
diff --git a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/Internal.java b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/Internal.java
index e5a98a22eb71cae46ddad53897953989485cd5c9..c77b2e404f7fe46f7c3dd1f9d1deb1d6e8d0369c 100644
--- a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/Internal.java
+++ b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/Internal.java
@@ -125,7 +125,7 @@ public abstract class Internal extends RBuiltinNode {
                     "pweibull", "qweibull", "dnchisq", "pnchisq", "qnchisq", "dnt", "pnt", "qnt", "dwilcox", "pwilcox", "qwilcox", "besselI", "besselK", "dnbinom_mu", "pnbinom_mu", "qnbinom_mu",
                     "dhyper", "phyper", "qhyper", "dnbeta", "pnbeta", "qnbeta", "dnf", "pnf", "qnf", "dtukey", "ptukey", "qtukey", "rchisq", "rexp", "rgeom", "rpois", "rt", "rsignrank", "rbeta",
                     "rbinom", "rcauchy", "rf", "rgamma", "rlnorm", "rlogis", "rnbinom", "rnbinom_mu", "rnchisq", "rnorm", "runif", "rweibull", "rwilcox", "rhyper", "sample2", "format.info",
-                    "grepRaw", "regexec", "adist", "aregexec", "chartr", "intToBits", "rawToBits", "packBits", "utf8ToInt", "intToUtf8", "strtrim", "eapply", "machine", "save",
+                    "grepRaw", "regexec", "adist", "aregexec", "chartr", "intToBits", "rawToBits", "packBits", "intToUtf8", "strtrim", "eapply", "machine", "save",
                     "saveToConn", "dput", "dump", "prmatrix", "gcinfo", "gctorture", "gctorture2", "memory.profile", "recordGraphics", "sys.calls", "sys.on.exit", "rank", "builtins", "bodyCode",
                     "rapply", "islistfactor", "inspect", "mem.limits", "merge", "capabilitiesX11", "Cstack_info", "file.show", "file.choose", "polyroot", "mkCode", "bcClose", "is.builtin.internal",
                     "disassemble", "bcVersion", "load.from.file", "save.to.file", "growconst", "putconst", "getconst", "enableJIT", "setNumMathThreads", "setMaxNumMathThreads", "isatty",
diff --git a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/Lapply.java b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/Lapply.java
index 54ecf0b6dc9db4eaf3fcfd74062c55e6372bb18c..4cd34ed9f441d06c369bdfc1c72c98880a2d1d24 100644
--- a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/Lapply.java
+++ b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/Lapply.java
@@ -17,7 +17,6 @@ import static com.oracle.truffle.r.runtime.builtins.RBuiltinKind.INTERNAL;
 
 import com.oracle.truffle.api.CompilerAsserts;
 import com.oracle.truffle.api.CompilerDirectives;
-import com.oracle.truffle.api.CompilerDirectives.CompilationFinal;
 import com.oracle.truffle.api.dsl.Cached;
 import com.oracle.truffle.api.dsl.Specialization;
 import com.oracle.truffle.api.frame.Frame;
@@ -89,21 +88,18 @@ public abstract class Lapply extends RBuiltinNode {
 
     private static final class ExtractElementInternal extends RSourceSectionNode implements RSyntaxCall {
 
-        protected ExtractElementInternal() {
+        @Child private ExtractVectorNode extractElementNode = ExtractVectorNodeGen.create(ElementAccessMode.SUBSCRIPT, false);
+        private final FrameSlot vectorSlot;
+        private final FrameSlot indexSlot;
+
+        protected ExtractElementInternal(FrameSlot vectorSlot, FrameSlot indexSlot) {
             super(RSyntaxNode.LAZY_DEPARSE);
+            this.vectorSlot = vectorSlot;
+            this.indexSlot = indexSlot;
         }
 
-        @Child private ExtractVectorNode extractElementNode = ExtractVectorNodeGen.create(ElementAccessMode.SUBSCRIPT, false);
-        @CompilationFinal private FrameSlot vectorSlot;
-        @CompilationFinal private FrameSlot indexSlot;
-
         @Override
         public Object execute(VirtualFrame frame) {
-            if (vectorSlot == null) {
-                CompilerDirectives.transferToInterpreterAndInvalidate();
-                vectorSlot = frame.getFrameDescriptor().findFrameSlot("X");
-                indexSlot = frame.getFrameDescriptor().findFrameSlot("i");
-            }
             try {
                 return extractElementNode.apply(frame, frame.getObject(vectorSlot), new Object[]{frame.getInt(indexSlot)}, RRuntime.LOGICAL_TRUE, RRuntime.LOGICAL_TRUE);
             } catch (FrameSlotTypeException e) {
@@ -149,8 +145,8 @@ public abstract class Lapply extends RBuiltinNode {
                         @Cached("createVectorSlot(frame)") FrameSlot vectorSlot, //
                         @Cached("create()") RLengthNode lengthNode, //
                         @Cached("createCountingProfile()") LoopConditionProfile loop, //
-                        @Cached("createCallNode()") RCallNode firstCallNode, //
-                        @Cached("createCallNode()") RCallNode callNode) {
+                        @Cached("createCallNode(vectorSlot, indexSlot)") RCallNode firstCallNode, //
+                        @Cached("createCallNode(vectorSlot, indexSlot)") RCallNode callNode) {
             // TODO: R switches to double if x.getLength() is greater than 2^31-1
             frame.setObject(vectorSlot, vector);
             int length = lengthNode.executeInteger(frame, vector);
@@ -171,10 +167,10 @@ public abstract class Lapply extends RBuiltinNode {
         /**
          * Creates the {@link RCallNode} for this target and {@code varArgs}.
          */
-        protected RCallNode createCallNode() {
+        protected RCallNode createCallNode(FrameSlot vectorSlot, FrameSlot indexSlot) {
             CompilerAsserts.neverPartOfCompilation();
 
-            ExtractElementInternal element = new ExtractElementInternal();
+            ExtractElementInternal element = new ExtractElementInternal(vectorSlot, indexSlot);
             ReadVariableNode readArgs = ReadVariableNode.createSilent(ArgumentsSignature.VARARG_NAME, RType.Any);
 
             return RCallNode.createCall(createCallSourceSection(), ReadVariableNode.create("FUN"), ArgumentsSignature.get(null, "..."), element, readArgs);
diff --git a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/R/dataframe_overrides.R b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/R/dataframe_overrides.R
deleted file mode 100644
index 2d61513b5326ac326cbce80dd9e4cfdd02fad0f9..0000000000000000000000000000000000000000
--- a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/R/dataframe_overrides.R
+++ /dev/null
@@ -1,30 +0,0 @@
-#  File src/library/base/R/dataframe.R
-#  Part of the R package, http://www.R-project.org
-#
-#  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.
-#
-#  A copy of the GNU General Public License is available at
-#  http://www.r-project.org/Licenses/
-
-# Statlib code by John Chambers, Bell Labs, 1994
-# Changes Copyright (C) 1998-2014 The R Core Team
-
-Summary.data.frame <- function(..., na.rm=FALSE)
-{
-    args <- list(...)
-    args <- lapply(args, function(x) {
-        x <- as.matrix(x)
-        if(!is.numeric(x) && !is.complex(x))
-            stop("only defined on a data frame with all numeric variables")
-        x
-    })
-    do.call(.Generic, c(args, na.rm=na.rm))
-}
diff --git a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/SetTimeLimit.java b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/SetTimeLimit.java
index 61e0a0edaf5a66fe8db29e29cfc1ad77115ca4b4..36c4516371412297a7aae02450ddebee22b158d0 100644
--- a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/SetTimeLimit.java
+++ b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/SetTimeLimit.java
@@ -23,6 +23,7 @@
 package com.oracle.truffle.r.nodes.builtin.base;
 
 import static com.oracle.truffle.r.nodes.builtin.CastBuilder.Predef.*;
+import static com.oracle.truffle.r.runtime.RVisibility.OFF;
 import static com.oracle.truffle.r.runtime.builtins.RBehavior.COMPLEX;
 import static com.oracle.truffle.r.runtime.builtins.RBuiltinKind.INTERNAL;
 
@@ -32,7 +33,7 @@ import com.oracle.truffle.r.nodes.builtin.RBuiltinNode;
 import com.oracle.truffle.r.runtime.builtins.RBuiltin;
 import com.oracle.truffle.r.runtime.data.RNull;
 
-@RBuiltin(name = "setTimeLimit", kind = INTERNAL, parameterNames = {"cpu", "elapsed", "transient"}, behavior = COMPLEX)
+@RBuiltin(name = "setTimeLimit", kind = INTERNAL, parameterNames = {"cpu", "elapsed", "transient"}, visibility = OFF, behavior = COMPLEX)
 public abstract class SetTimeLimit extends RBuiltinNode {
 
     @Override
diff --git a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/Sprintf.java b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/Sprintf.java
index 2f1abb16b37e693639d363d1bbbc79e6e41a5e40..99d18142da4efbbeff608c53fbf2b8cabc9b265c 100644
--- a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/Sprintf.java
+++ b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/Sprintf.java
@@ -52,7 +52,7 @@ public abstract class Sprintf extends RBuiltinNode {
     @Child private Sprintf sprintfRecursive;
 
     @Specialization
-    protected RStringVector sprintf(RAbstractStringVector fmt, @SuppressWarnings("unused") RNull x) {
+    protected RStringVector sprintf(@SuppressWarnings("unused") RAbstractStringVector fmt, @SuppressWarnings("unused") RNull x) {
         return RDataFactory.createEmptyStringVector();
     }
 
diff --git a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/SysFunctions.java b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/SysFunctions.java
index b020cfb2189514bbc70feaadb3186a4504db4033..3b5192cb48877a010dba5cd174f49da29a25f24c 100644
--- a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/SysFunctions.java
+++ b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/SysFunctions.java
@@ -382,7 +382,7 @@ public class SysFunctions {
         }
     }
 
-    @RBuiltin(name = "setFileTime", kind = INTERNAL, parameterNames = {"path", "time"}, behavior = IO)
+    @RBuiltin(name = "setFileTime", kind = INTERNAL, parameterNames = {"path", "time"}, visibility = OFF, behavior = IO)
     public abstract static class SysSetFileTime extends RBuiltinNode {
         @Override
         protected void createCasts(CastBuilder casts) {
diff --git a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/UpdateAttr.java b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/UpdateAttr.java
index 34c1d680f8290eead7dfaabaed28894cabb35bd4..44c90112eea01405a565a31844f320978bcabf50 100644
--- a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/UpdateAttr.java
+++ b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/UpdateAttr.java
@@ -29,17 +29,21 @@ import static com.oracle.truffle.r.runtime.builtins.RBehavior.PURE;
 import static com.oracle.truffle.r.runtime.builtins.RBuiltinKind.PRIMITIVE;
 
 import com.oracle.truffle.api.CompilerDirectives;
-import com.oracle.truffle.api.CompilerDirectives.CompilationFinal;
 import com.oracle.truffle.api.CompilerDirectives.TruffleBoundary;
+import com.oracle.truffle.api.dsl.Cached;
 import com.oracle.truffle.api.dsl.Fallback;
 import com.oracle.truffle.api.dsl.Specialization;
+import com.oracle.truffle.api.dsl.TypeSystemReference;
+import com.oracle.truffle.api.nodes.Node;
 import com.oracle.truffle.api.profiles.BranchProfile;
+import com.oracle.truffle.r.nodes.EmptyTypeSystemFlatLayout;
 import com.oracle.truffle.r.nodes.attributes.SetAttributeNode;
 import com.oracle.truffle.r.nodes.attributes.SpecialAttributesFunctions.SetClassAttributeNode;
 import com.oracle.truffle.r.nodes.attributes.SpecialAttributesFunctions.SetDimAttributeNode;
 import com.oracle.truffle.r.nodes.attributes.SpecialAttributesFunctions.SetRowNamesAttributeNode;
 import com.oracle.truffle.r.nodes.builtin.CastBuilder;
 import com.oracle.truffle.r.nodes.builtin.RBuiltinNode;
+import com.oracle.truffle.r.nodes.builtin.base.UpdateAttrNodeGen.InternStringNodeGen;
 import com.oracle.truffle.r.nodes.unary.CastIntegerNode;
 import com.oracle.truffle.r.nodes.unary.CastIntegerNodeGen;
 import com.oracle.truffle.r.nodes.unary.CastListNode;
@@ -75,8 +79,25 @@ public abstract class UpdateAttr extends RBuiltinNode {
     @Child private SetAttributeNode setGenAttrNode;
     @Child private SetDimAttributeNode setDimNode;
 
-    @CompilationFinal private String cachedName = "";
-    @CompilationFinal private String cachedInternedName = "";
+    @Child private InternStringNode intern = InternStringNodeGen.create();
+
+    @TypeSystemReference(EmptyTypeSystemFlatLayout.class)
+    public abstract static class InternStringNode extends Node {
+
+        public abstract String execute(String value);
+
+        @Specialization(limit = "3", guards = "value == cachedValue")
+        protected static String internCached(@SuppressWarnings("unused") String value,
+                        @SuppressWarnings("unused") @Cached("value") String cachedValue,
+                        @Cached("intern(value)") String interned) {
+            return interned;
+        }
+
+        @Specialization(contains = "internCached")
+        protected static String intern(String value) {
+            return Utils.intern(value);
+        }
+    }
 
     @Override
     protected void createCasts(CastBuilder casts) {
@@ -118,31 +139,9 @@ public abstract class UpdateAttr extends RBuiltinNode {
         return (RAbstractVector) castVector.execute(value);
     }
 
-    private String intern(String name) {
-        if (cachedName == null) {
-            // unoptimized case
-            return Utils.intern(name);
-        }
-        if (cachedName == name) {
-            // cached case
-            return cachedInternedName;
-        }
-        CompilerDirectives.transferToInterpreterAndInvalidate();
-        // Checkstyle: stop StringLiteralEquality
-        if (cachedName == "") {
-            // Checkstyle: resume StringLiteralEquality
-            cachedName = name;
-            cachedInternedName = Utils.intern(name);
-        } else {
-            cachedName = null;
-            cachedInternedName = null;
-        }
-        return Utils.intern(name);
-    }
-
     @Specialization
     protected RAbstractContainer updateAttr(RAbstractContainer container, String name, RNull value) {
-        String internedName = intern(name);
+        String internedName = intern.execute(name);
         RAbstractContainer result = (RAbstractContainer) container.getNonShared();
         // the name is interned, so identity comparison is sufficient
         if (internedName == RRuntime.DIM_ATTR_KEY) {
@@ -187,7 +186,7 @@ public abstract class UpdateAttr extends RBuiltinNode {
 
     @Specialization(guards = "!nullValue(value)")
     protected RAbstractContainer updateAttr(RAbstractContainer container, String name, Object value) {
-        String internedName = intern(name);
+        String internedName = intern.execute(name);
         RAbstractContainer result = (RAbstractContainer) container.getNonShared();
         // the name is interned, so identity comparison is sufficient
         if (internedName == RRuntime.DIM_ATTR_KEY) {
@@ -246,7 +245,7 @@ public abstract class UpdateAttr extends RBuiltinNode {
         if (object instanceof RShareable) {
             object = ((RShareable) object).getNonShared();
         }
-        String internedName = intern((String) name);
+        String internedName = intern.execute((String) name);
         if (object instanceof RAttributable) {
             RAttributable attributable = (RAttributable) object;
             if (value == RNull.instance) {
diff --git a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/UpdateClass.java b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/UpdateClass.java
index 094f7fb3b8b052cc251da25e495c326f181a1cf3..1133d63fa879b46b5bba99865a40c045c87690ab 100644
--- a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/UpdateClass.java
+++ b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/UpdateClass.java
@@ -18,7 +18,6 @@ import com.oracle.truffle.api.CompilerDirectives;
 import com.oracle.truffle.api.CompilerDirectives.TruffleBoundary;
 import com.oracle.truffle.api.dsl.Cached;
 import com.oracle.truffle.api.dsl.Specialization;
-import com.oracle.truffle.api.profiles.BranchProfile;
 import com.oracle.truffle.r.nodes.attributes.SpecialAttributesFunctions.SetClassAttributeNode;
 import com.oracle.truffle.r.nodes.attributes.TypeFromModeNode;
 import com.oracle.truffle.r.nodes.binary.CastTypeNode;
diff --git a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/Utf8ToInt.java b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/Utf8ToInt.java
new file mode 100644
index 0000000000000000000000000000000000000000..85b423645f69c4f0ac9df19b344c4d7be714a410
--- /dev/null
+++ b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/Utf8ToInt.java
@@ -0,0 +1,67 @@
+/*
+ * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package com.oracle.truffle.r.nodes.builtin.base;
+
+import static com.oracle.truffle.r.nodes.builtin.CastBuilder.Predef.notEmpty;
+import static com.oracle.truffle.r.nodes.builtin.CastBuilder.Predef.size;
+import static com.oracle.truffle.r.nodes.builtin.CastBuilder.Predef.stringValue;
+import static com.oracle.truffle.r.runtime.builtins.RBehavior.PURE;
+import static com.oracle.truffle.r.runtime.builtins.RBuiltinKind.INTERNAL;
+
+import com.oracle.truffle.api.dsl.Specialization;
+import com.oracle.truffle.r.nodes.builtin.CastBuilder;
+import com.oracle.truffle.r.nodes.builtin.RBuiltinNode;
+import com.oracle.truffle.r.runtime.RError;
+import com.oracle.truffle.r.runtime.RRuntime;
+import com.oracle.truffle.r.runtime.builtins.RBuiltin;
+import com.oracle.truffle.r.runtime.data.RDataFactory;
+import com.oracle.truffle.r.runtime.data.model.RAbstractIntVector;
+import com.oracle.truffle.r.runtime.data.model.RAbstractStringVector;
+
+@RBuiltin(name = "utf8ToInt", kind = INTERNAL, parameterNames = {"x"}, behavior = PURE)
+public abstract class Utf8ToInt extends RBuiltinNode {
+
+    @Override
+    protected void createCasts(CastBuilder casts) {
+        casts.arg(0, "x").defaultError(RError.SHOW_CALLER, RError.Message.ARG_MUST_BE_CHARACTER_VECTOR_LENGTH_ONE, "x").mustBe(stringValue()).asStringVector().mustBe(notEmpty()).shouldBe(size(1),
+                        RError.SHOW_CALLER, RError.Message.ARG_SHOULD_BE_CHARACTER_VECTOR_LENGTH_ONE).findFirst();
+    }
+
+    @Specialization
+    protected RAbstractIntVector utf8ToInt(String value) {
+        RAbstractIntVector ret;
+        if (!RRuntime.isNA(value)) {
+            int valueLen = value.length();
+            int[] result = new int[valueLen];
+            for (int i = 0; i < valueLen; i++) {
+                char c = value.charAt(i);
+                result[i] = c;
+            }
+            ret = RDataFactory.createIntVector(result, true);
+        } else { // NA_character_
+            ret = RDataFactory.createIntVector(new int[]{RRuntime.INT_NA}, false);
+        }
+        return ret;
+    }
+
+}
diff --git a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/Warning.java b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/Warning.java
index 64b2b539db2bc7035e609b4a8ef40b3d31008094..19b63fbff07f76ef87fccae9c5038fd70c4ad9e8 100644
--- a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/Warning.java
+++ b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/Warning.java
@@ -22,12 +22,13 @@
  */
 package com.oracle.truffle.r.nodes.builtin.base;
 
-import static com.oracle.truffle.r.nodes.builtin.CastBuilder.Predef.*;
+import static com.oracle.truffle.r.nodes.builtin.CastBuilder.Predef.notEmpty;
+import static com.oracle.truffle.r.nodes.builtin.CastBuilder.Predef.stringValue;
+import static com.oracle.truffle.r.nodes.builtin.CastBuilder.Predef.toBoolean;
 import static com.oracle.truffle.r.runtime.RVisibility.OFF;
 import static com.oracle.truffle.r.runtime.builtins.RBehavior.COMPLEX;
 import static com.oracle.truffle.r.runtime.builtins.RBuiltinKind.INTERNAL;
 
-import com.oracle.truffle.api.CompilerDirectives;
 import com.oracle.truffle.api.CompilerDirectives.TruffleBoundary;
 import com.oracle.truffle.api.dsl.Specialization;
 import com.oracle.truffle.r.nodes.builtin.CastBuilder;
@@ -51,7 +52,6 @@ public abstract class Warning extends RBuiltinNode {
     @Specialization
     @TruffleBoundary
     protected String warning(boolean call, boolean immediate, boolean noBreakWarning, String message) {
-        CompilerDirectives.transferToInterpreter();
         RErrorHandling.warningcallInternal(call, message, immediate, noBreakWarning);
         return message;
     }
diff --git a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/foreign/CallAndExternalFunctions.java b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/foreign/CallAndExternalFunctions.java
index 279790c9b7f5c15e33802be3b956aefe106a481d..41d336596c73db6503e0e88aef10138663730192 100644
--- a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/foreign/CallAndExternalFunctions.java
+++ b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/foreign/CallAndExternalFunctions.java
@@ -46,13 +46,19 @@ import com.oracle.truffle.r.library.stats.Cauchy.PCauchy;
 import com.oracle.truffle.r.library.stats.Cauchy.RCauchy;
 import com.oracle.truffle.r.library.stats.CdistNodeGen;
 import com.oracle.truffle.r.library.stats.Chisq;
+import com.oracle.truffle.r.library.stats.Chisq.RChisq;
 import com.oracle.truffle.r.library.stats.CompleteCases;
 import com.oracle.truffle.r.library.stats.CovcorNodeGen;
 import com.oracle.truffle.r.library.stats.CutreeNodeGen;
 import com.oracle.truffle.r.library.stats.DBeta;
+import com.oracle.truffle.r.library.stats.DHyper;
+import com.oracle.truffle.r.library.stats.DNBeta;
+import com.oracle.truffle.r.library.stats.DNChisq;
+import com.oracle.truffle.r.library.stats.DNorm;
 import com.oracle.truffle.r.library.stats.DPois;
 import com.oracle.truffle.r.library.stats.Dbinom;
 import com.oracle.truffle.r.library.stats.Df;
+import com.oracle.truffle.r.library.stats.Dnf;
 import com.oracle.truffle.r.library.stats.DoubleCentreNodeGen;
 import com.oracle.truffle.r.library.stats.Dt;
 import com.oracle.truffle.r.library.stats.Exp.DExp;
@@ -68,33 +74,55 @@ import com.oracle.truffle.r.library.stats.LogNormal;
 import com.oracle.truffle.r.library.stats.LogNormal.DLNorm;
 import com.oracle.truffle.r.library.stats.LogNormal.PLNorm;
 import com.oracle.truffle.r.library.stats.LogNormal.QLNorm;
+import com.oracle.truffle.r.library.stats.Logis;
+import com.oracle.truffle.r.library.stats.Logis.DLogis;
+import com.oracle.truffle.r.library.stats.Logis.RLogis;
+import com.oracle.truffle.r.library.stats.PGamma;
+import com.oracle.truffle.r.library.stats.PHyper;
+import com.oracle.truffle.r.library.stats.PNBeta;
+import com.oracle.truffle.r.library.stats.PNChisq;
+import com.oracle.truffle.r.library.stats.PPois;
 import com.oracle.truffle.r.library.stats.Pbeta;
 import com.oracle.truffle.r.library.stats.Pbinom;
 import com.oracle.truffle.r.library.stats.Pf;
+import com.oracle.truffle.r.library.stats.Pnf;
 import com.oracle.truffle.r.library.stats.Pnorm;
+import com.oracle.truffle.r.library.stats.Pt;
+import com.oracle.truffle.r.library.stats.QBeta;
+import com.oracle.truffle.r.library.stats.QHyper;
+import com.oracle.truffle.r.library.stats.QNBeta;
+import com.oracle.truffle.r.library.stats.QNChisq;
+import com.oracle.truffle.r.library.stats.QPois;
 import com.oracle.truffle.r.library.stats.Qbinom;
+import com.oracle.truffle.r.library.stats.Qf;
+import com.oracle.truffle.r.library.stats.Qnf;
 import com.oracle.truffle.r.library.stats.Qnorm;
+import com.oracle.truffle.r.library.stats.Qt;
 import com.oracle.truffle.r.library.stats.RBeta;
-import com.oracle.truffle.r.library.stats.RChisq;
 import com.oracle.truffle.r.library.stats.RGamma;
 import com.oracle.truffle.r.library.stats.RHyper;
-import com.oracle.truffle.r.library.stats.RLogis;
 import com.oracle.truffle.r.library.stats.RMultinomNodeGen;
 import com.oracle.truffle.r.library.stats.RNbinomMu;
 import com.oracle.truffle.r.library.stats.RNchisq;
 import com.oracle.truffle.r.library.stats.RPois;
 import com.oracle.truffle.r.library.stats.RWeibull;
 import com.oracle.truffle.r.library.stats.RandGenerationFunctions;
-import com.oracle.truffle.r.library.stats.RandGenerationFunctionsFactory;
+import com.oracle.truffle.r.library.stats.RandGenerationFunctions.RandFunction1Node;
+import com.oracle.truffle.r.library.stats.RandGenerationFunctions.RandFunction2Node;
+import com.oracle.truffle.r.library.stats.RandGenerationFunctions.RandFunction3Node;
 import com.oracle.truffle.r.library.stats.Rbinom;
 import com.oracle.truffle.r.library.stats.Rf;
 import com.oracle.truffle.r.library.stats.Rnorm;
 import com.oracle.truffle.r.library.stats.Rt;
-import com.oracle.truffle.r.library.stats.Runif;
 import com.oracle.truffle.r.library.stats.Signrank.RSignrank;
 import com.oracle.truffle.r.library.stats.SplineFunctionsFactory.SplineCoefNodeGen;
 import com.oracle.truffle.r.library.stats.SplineFunctionsFactory.SplineEvalNodeGen;
+import com.oracle.truffle.r.library.stats.StatsFunctions;
 import com.oracle.truffle.r.library.stats.StatsFunctionsFactory;
+import com.oracle.truffle.r.library.stats.Unif.DUnif;
+import com.oracle.truffle.r.library.stats.Unif.PUnif;
+import com.oracle.truffle.r.library.stats.Unif.QUnif;
+import com.oracle.truffle.r.library.stats.Unif.Runif;
 import com.oracle.truffle.r.library.stats.Wilcox.RWilcox;
 import com.oracle.truffle.r.library.tools.C_ParseRdNodeGen;
 import com.oracle.truffle.r.library.tools.DirChmodNodeGen;
@@ -140,7 +168,7 @@ import com.oracle.truffle.r.runtime.ffi.RFFIFactory;
 public class CallAndExternalFunctions {
 
     @TruffleBoundary
-    protected static Object encodeArgumentPairList(RArgsValuesAndNames args, String symbolName) {
+    private static Object encodeArgumentPairList(RArgsValuesAndNames args, String symbolName) {
         Object list = RNull.instance;
         for (int i = args.getLength() - 1; i >= 0; i--) {
             String name = args.getSignature().getName(i);
@@ -150,8 +178,8 @@ public class CallAndExternalFunctions {
         return list;
     }
 
-    protected abstract static class CallRFFIAdapter extends LookupAdapter {
-        @Child protected CallRFFI.CallRFFINode callRFFINode = RFFIFactory.getRFFI().getCallRFFI().createCallRFFINode();
+    abstract static class CallRFFIAdapter extends LookupAdapter {
+        @Child CallRFFI.CallRFFINode callRFFINode = RFFIFactory.getRFFI().getCallRFFI().createCallRFFINode();
     }
 
     /**
@@ -249,53 +277,81 @@ public class CallAndExternalFunctions {
                 case "qnorm":
                     return StatsFunctionsFactory.Function3_2NodeGen.create(new Qnorm());
                 case "rnorm":
-                    return RandGenerationFunctionsFactory.Function2_DoubleNodeGen.create(new Rnorm());
+                    return RandFunction2Node.createDouble(new Rnorm());
                 case "runif":
-                    return RandGenerationFunctionsFactory.Function2_DoubleNodeGen.create(new Runif());
+                    return RandFunction2Node.createDouble(new Runif());
                 case "rbeta":
-                    return RandGenerationFunctionsFactory.Function2_DoubleNodeGen.create(new RBeta());
+                    return RandFunction2Node.createDouble(new RBeta());
                 case "rgamma":
-                    return RandGenerationFunctionsFactory.Function2_DoubleNodeGen.create(new RGamma());
+                    return RandFunction2Node.createDouble(new RGamma());
                 case "rcauchy":
-                    return RandGenerationFunctionsFactory.Function2_DoubleNodeGen.create(new RCauchy());
+                    return RandFunction2Node.createDouble(new RCauchy());
                 case "rf":
-                    return RandGenerationFunctionsFactory.Function2_DoubleNodeGen.create(new Rf());
+                    return RandFunction2Node.createDouble(new Rf());
                 case "rlogis":
-                    return RandGenerationFunctionsFactory.Function2_DoubleNodeGen.create(new RLogis());
+                    return RandFunction2Node.createDouble(new RLogis());
                 case "rweibull":
-                    return RandGenerationFunctionsFactory.Function2_DoubleNodeGen.create(new RWeibull());
+                    return RandFunction2Node.createDouble(new RWeibull());
                 case "rnchisq":
-                    return RandGenerationFunctionsFactory.Function2_DoubleNodeGen.create(new RNchisq());
+                    return RandFunction2Node.createDouble(new RNchisq());
                 case "rnbinom_mu":
-                    return RandGenerationFunctionsFactory.Function2_DoubleNodeGen.create(new RNbinomMu());
+                    return RandFunction2Node.createDouble(new RNbinomMu());
                 case "rwilcox":
-                    return RandGenerationFunctionsFactory.Function2_IntNodeGen.create(new RWilcox());
+                    return RandFunction2Node.createInt(new RWilcox());
                 case "rchisq":
-                    return RandGenerationFunctionsFactory.Function1_DoubleNodeGen.create(new RChisq());
+                    return RandFunction1Node.createDouble(new RChisq());
                 case "rexp":
-                    return RandGenerationFunctionsFactory.Function1_DoubleNodeGen.create(new RExp());
+                    return RandFunction1Node.createDouble(new RExp());
                 case "rgeom":
-                    return RandGenerationFunctionsFactory.Function1_IntNodeGen.create(new RGeom());
+                    return RandFunction1Node.createInt(new RGeom());
                 case "rpois":
-                    return RandGenerationFunctionsFactory.Function1_IntNodeGen.create(new RPois());
+                    return RandFunction1Node.createInt(new RPois());
                 case "rt":
-                    return RandGenerationFunctionsFactory.Function1_DoubleNodeGen.create(new Rt());
+                    return RandFunction1Node.createDouble(new Rt());
                 case "rsignrank":
-                    return RandGenerationFunctionsFactory.Function1_IntNodeGen.create(new RSignrank());
+                    return RandFunction1Node.createInt(new RSignrank());
                 case "rhyper":
-                    return RandGenerationFunctionsFactory.Function3_IntNodeGen.create(new RHyper());
+                    return RandFunction3Node.createInt(new RHyper());
+                case "phyper":
+                    return StatsFunctions.Function4_2Node.create(new PHyper());
+                case "dhyper":
+                    return StatsFunctions.Function4_1Node.create(new DHyper());
+                case "qhyper":
+                    return StatsFunctions.Function4_2Node.create(new QHyper());
+                case "pnchisq":
+                    return StatsFunctionsFactory.Function3_2NodeGen.create(new PNChisq());
+                case "qnchisq":
+                    return StatsFunctionsFactory.Function3_2NodeGen.create(new QNChisq());
+                case "dnchisq":
+                    return StatsFunctionsFactory.Function3_1NodeGen.create(new DNChisq());
+                case "qt":
+                    return StatsFunctionsFactory.Function2_2NodeGen.create(new Qt());
+                case "pt":
+                    return StatsFunctionsFactory.Function2_2NodeGen.create(new Pt());
                 case "qgamma":
                     return StatsFunctionsFactory.Function3_2NodeGen.create(new QgammaFunc());
                 case "dbinom":
                     return StatsFunctionsFactory.Function3_1NodeGen.create(new Dbinom());
                 case "qbinom":
                     return StatsFunctionsFactory.Function3_2NodeGen.create(new Qbinom());
+                case "punif":
+                    return StatsFunctionsFactory.Function3_2NodeGen.create(new PUnif());
+                case "dunif":
+                    return StatsFunctionsFactory.Function3_1NodeGen.create(new DUnif());
+                case "qunif":
+                    return StatsFunctionsFactory.Function3_2NodeGen.create(new QUnif());
+                case "ppois":
+                    return StatsFunctionsFactory.Function2_2NodeGen.create(new PPois());
+                case "qpois":
+                    return StatsFunctionsFactory.Function2_2NodeGen.create(new QPois());
                 case "rbinom":
-                    return RandGenerationFunctionsFactory.Function2_IntNodeGen.create(new Rbinom());
+                    return RandFunction2Node.createInt(new Rbinom());
                 case "pbinom":
                     return StatsFunctionsFactory.Function3_2NodeGen.create(new Pbinom());
                 case "pbeta":
                     return StatsFunctionsFactory.Function3_2NodeGen.create(new Pbeta());
+                case "qbeta":
+                    return StatsFunctionsFactory.Function3_2NodeGen.create(new QBeta());
                 case "dcauchy":
                     return StatsFunctionsFactory.Function3_1NodeGen.create(new DCauchy());
                 case "pcauchy":
@@ -304,12 +360,18 @@ public class CallAndExternalFunctions {
                     return StatsFunctionsFactory.Function3_2NodeGen.create(new Cauchy.QCauchy());
                 case "pf":
                     return StatsFunctionsFactory.Function3_2NodeGen.create(new Pf());
+                case "qf":
+                    return StatsFunctionsFactory.Function3_2NodeGen.create(new Qf());
                 case "df":
                     return StatsFunctionsFactory.Function3_1NodeGen.create(new Df());
                 case "dgamma":
                     return StatsFunctionsFactory.Function3_1NodeGen.create(new DGamma());
+                case "pgamma":
+                    return StatsFunctionsFactory.Function3_2NodeGen.create(new PGamma());
                 case "dchisq":
                     return StatsFunctionsFactory.Function2_1NodeGen.create(new Chisq.DChisq());
+                case "qchisq":
+                    return StatsFunctionsFactory.Function2_2NodeGen.create(new Chisq.QChisq());
                 case "qgeom":
                     return StatsFunctionsFactory.Function2_2NodeGen.create(new Geom.QGeom());
                 case "pchisq":
@@ -326,16 +388,36 @@ public class CallAndExternalFunctions {
                     return StatsFunctionsFactory.Function2_1NodeGen.create(new DPois());
                 case "dbeta":
                     return StatsFunctionsFactory.Function3_1NodeGen.create(new DBeta());
+                case "dnbeta":
+                    return StatsFunctions.Function4_1Node.create(new DNBeta());
+                case "qnbeta":
+                    return StatsFunctions.Function4_2Node.create(new QNBeta());
+                case "dnf":
+                    return StatsFunctions.Function4_1Node.create(new Dnf());
+                case "qnf":
+                    return StatsFunctions.Function4_2Node.create(new Qnf());
+                case "pnf":
+                    return StatsFunctions.Function4_2Node.create(new Pnf());
+                case "pnbeta":
+                    return StatsFunctions.Function4_2Node.create(new PNBeta());
                 case "dt":
                     return StatsFunctionsFactory.Function2_1NodeGen.create(new Dt());
                 case "rlnorm":
-                    return RandGenerationFunctionsFactory.Function2_DoubleNodeGen.create(new LogNormal.RLNorm());
+                    return RandFunction2Node.createDouble(new LogNormal.RLNorm());
                 case "dlnorm":
                     return StatsFunctionsFactory.Function3_1NodeGen.create(new DLNorm());
                 case "qlnorm":
                     return StatsFunctionsFactory.Function3_2NodeGen.create(new QLNorm());
                 case "plnorm":
                     return StatsFunctionsFactory.Function3_2NodeGen.create(new PLNorm());
+                case "dlogis":
+                    return StatsFunctionsFactory.Function3_1NodeGen.create(new DLogis());
+                case "qlogis":
+                    return StatsFunctionsFactory.Function3_2NodeGen.create(new Logis.QLogis());
+                case "plogis":
+                    return StatsFunctionsFactory.Function3_2NodeGen.create(new Logis.PLogis());
+                case "pgeom":
+                    return StatsFunctionsFactory.Function2_2NodeGen.create(new Geom.PGeom());
                 case "rmultinom":
                     return RMultinomNodeGen.create();
                 case "Approx":
@@ -429,7 +511,7 @@ public class CallAndExternalFunctions {
                     return new RInternalCodeBuiltinNode(RContext.getInstance(), "stats", RInternalCode.loadSourceRelativeTo(RandGenerationFunctions.class, "lm.R"), "Cdqrls");
 
                 case "dnorm":
-                    return StatsFunctionsFactory.Function3_1NodeGen.create(new Dnorm4());
+                    return StatsFunctionsFactory.Function3_1NodeGen.create(new DNorm());
 
                 // tools
                 case "doTabExpand":
diff --git a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/infix/AccessField.java b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/infix/AccessField.java
index 9f848c51562ad640a6ac5c7331ebdd9be1c13c2b..9a435cdd16cbe7f67f6ab016b157a05ddf5f9ab0 100644
--- a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/infix/AccessField.java
+++ b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/infix/AccessField.java
@@ -39,7 +39,6 @@ import com.oracle.truffle.r.nodes.EmptyTypeSystemFlatLayout;
 import com.oracle.truffle.r.nodes.access.vector.ElementAccessMode;
 import com.oracle.truffle.r.nodes.access.vector.ExtractListElement;
 import com.oracle.truffle.r.nodes.access.vector.ExtractVectorNode;
-import com.oracle.truffle.r.nodes.attributes.SpecialAttributesFunctions.GetNamesAttributeNode;
 import com.oracle.truffle.r.nodes.builtin.CastBuilder;
 import com.oracle.truffle.r.nodes.builtin.RBuiltinNode;
 import com.oracle.truffle.r.runtime.ArgumentsSignature;
@@ -49,6 +48,7 @@ import com.oracle.truffle.r.runtime.RType;
 import com.oracle.truffle.r.runtime.builtins.RBuiltin;
 import com.oracle.truffle.r.runtime.builtins.RSpecialFactory;
 import com.oracle.truffle.r.runtime.data.RList;
+import com.oracle.truffle.r.runtime.data.RStringVector;
 import com.oracle.truffle.r.runtime.data.model.RAbstractListVector;
 import com.oracle.truffle.r.runtime.data.model.RAbstractVector;
 import com.oracle.truffle.r.runtime.nodes.RNode;
@@ -59,19 +59,24 @@ abstract class AccessFieldSpecial extends SpecialsUtils.ListFieldSpecialBase {
 
     @Child private ExtractListElement extractListElement = ExtractListElement.create();
 
-    @Specialization(guards = {"isSimpleList(list)", "isCached(list, field)", "list.getNames() != null"})
-    public Object doList(RList list, String field,
-                    @Cached("getIndex(list.getNames(), field)") int index) {
+    @Specialization(limit = "2", guards = {"isSimpleList(list)", "list.getNames() == cachedNames", "field == cachedField"})
+    public Object doList(RList list, @SuppressWarnings("unused") String field,
+                    @SuppressWarnings("unused") @Cached("list.getNames()") RStringVector cachedNames,
+                    @SuppressWarnings("unused") @Cached("field") String cachedField,
+                    @Cached("getIndex(cachedNames, field)") int index) {
         if (index == -1) {
             throw RSpecialFactory.throwFullCallNeeded();
         }
-        updateCache(list, field);
         return extractListElement.execute(list, index);
     }
 
     @Specialization(contains = "doList", guards = {"isSimpleList(list)", "list.getNames() != null"})
-    public Object doListDynamic(RList list, String field, @Cached("create()") GetNamesAttributeNode getNamesNode) {
-        return doList(list, field, getIndex(getNamesNode.getNames(list), field));
+    public Object doListDynamic(RList list, String field) {
+        int index = getIndex(getNamesNode.getNames(list), field);
+        if (index == -1) {
+            throw RSpecialFactory.throwFullCallNeeded();
+        }
+        return extractListElement.execute(list, index);
     }
 
     @Fallback
@@ -82,6 +87,7 @@ abstract class AccessFieldSpecial extends SpecialsUtils.ListFieldSpecialBase {
 }
 
 @RBuiltin(name = "$", kind = PRIMITIVE, parameterNames = {"", ""}, dispatch = INTERNAL_GENERIC, behavior = PURE)
+@TypeSystemReference(EmptyTypeSystemFlatLayout.class)
 public abstract class AccessField extends RBuiltinNode {
 
     @Child private ExtractVectorNode extract = ExtractVectorNode.create(ElementAccessMode.SUBSCRIPT, true);
diff --git a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/infix/ParenBuiltin.java b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/infix/ParenBuiltin.java
index 23c4c9cbf938de9aa25c65137c0498499e9cb009..a8655bf30d7bebc0b629f7f17af748376f1d30a5 100644
--- a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/infix/ParenBuiltin.java
+++ b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/infix/ParenBuiltin.java
@@ -22,19 +22,45 @@
  */
 package com.oracle.truffle.r.nodes.builtin.base.infix;
 
+import static com.oracle.truffle.r.runtime.RVisibility.ON;
 import static com.oracle.truffle.r.runtime.builtins.RBehavior.PURE;
 import static com.oracle.truffle.r.runtime.builtins.RBuiltinKind.PRIMITIVE;
 
-import com.oracle.truffle.api.dsl.Specialization;
+import com.oracle.truffle.api.frame.VirtualFrame;
+import com.oracle.truffle.api.nodes.NodeCost;
+import com.oracle.truffle.api.nodes.NodeInfo;
 import com.oracle.truffle.r.nodes.builtin.RBuiltinNode;
-import com.oracle.truffle.r.runtime.RInternalError;
+import com.oracle.truffle.r.runtime.ArgumentsSignature;
 import com.oracle.truffle.r.runtime.builtins.RBuiltin;
+import com.oracle.truffle.r.runtime.nodes.RNode;
 
-@RBuiltin(name = "(", kind = PRIMITIVE, parameterNames = {"x"}, behavior = PURE)
-public abstract class ParenBuiltin extends RBuiltinNode {
-    @SuppressWarnings("unused")
-    @Specialization
-    protected Object doIt(Object x) {
-        throw RInternalError.unimplemented();
+@NodeInfo(cost = NodeCost.NONE)
+final class ParensSpecial extends RNode {
+
+    @Child private RNode delegate;
+
+    protected ParensSpecial(RNode delegate) {
+        this.delegate = delegate;
+    }
+
+    @Override
+    public Object execute(VirtualFrame frame) {
+        return delegate.execute(frame);
+    }
+}
+
+@RBuiltin(name = "(", kind = PRIMITIVE, parameterNames = {""}, visibility = ON, behavior = PURE)
+public final class ParenBuiltin extends RBuiltinNode {
+
+    public static RNode special(ArgumentsSignature signature, RNode[] args, @SuppressWarnings("unused") boolean inReplacement) {
+        if (signature == ArgumentsSignature.empty(1)) {
+            return new ParensSpecial(args[0]);
+        }
+        return null;
+    }
+
+    @Override
+    public Object executeBuiltin(VirtualFrame frame, Object... args) {
+        return args[0];
     }
 }
diff --git a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/infix/SpecialsUtils.java b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/infix/SpecialsUtils.java
index 793d882e1a8121d8e29bcbdbcd993e9b78bbe6d3..971e6e19765f800c98f1d7d9f958ceacecb3440b 100644
--- a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/infix/SpecialsUtils.java
+++ b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/infix/SpecialsUtils.java
@@ -23,16 +23,27 @@
 package com.oracle.truffle.r.nodes.builtin.base.infix;
 
 import com.oracle.truffle.api.CompilerDirectives;
-import com.oracle.truffle.api.CompilerDirectives.CompilationFinal;
 import com.oracle.truffle.api.CompilerDirectives.TruffleBoundary;
+import com.oracle.truffle.api.dsl.NodeChild;
+import com.oracle.truffle.api.dsl.NodeChildren;
+import com.oracle.truffle.api.dsl.Specialization;
+import com.oracle.truffle.api.dsl.TypeSystemReference;
+import com.oracle.truffle.api.frame.VirtualFrame;
+import com.oracle.truffle.api.nodes.NodeCost;
+import com.oracle.truffle.api.nodes.NodeInfo;
 import com.oracle.truffle.api.profiles.ValueProfile;
+import com.oracle.truffle.r.nodes.EmptyTypeSystemFlatLayout;
+import com.oracle.truffle.r.nodes.attributes.SpecialAttributesFunctions.GetDimAttributeNode;
 import com.oracle.truffle.r.nodes.attributes.SpecialAttributesFunctions.GetNamesAttributeNode;
+import com.oracle.truffle.r.nodes.builtin.base.infix.SpecialsUtilsFactory.ConvertIndexNodeGen;
 import com.oracle.truffle.r.nodes.function.ClassHierarchyNode;
 import com.oracle.truffle.r.runtime.ArgumentsSignature;
 import com.oracle.truffle.r.runtime.data.RList;
 import com.oracle.truffle.r.runtime.data.RStringVector;
 import com.oracle.truffle.r.runtime.data.model.RAbstractVector;
+import com.oracle.truffle.r.runtime.nodes.RBaseNode;
 import com.oracle.truffle.r.runtime.nodes.RNode;
+import com.oracle.truffle.r.runtime.nodes.RSyntaxNode;
 
 /**
  * Helper methods for implementing special calls.
@@ -43,72 +54,86 @@ class SpecialsUtils {
     private static final String valueArgName = "value".intern();
 
     public static boolean isCorrectUpdateSignature(ArgumentsSignature signature) {
-        return signature.getLength() == 3 && signature.getName(0) == null && signature.getName(1) == null && signature.getName(2) == valueArgName;
+        if (signature.getLength() == 3) {
+            return signature.getName(0) == null && signature.getName(1) == null && signature.getName(2) == valueArgName;
+        } else if (signature.getLength() == 4) {
+            return signature.getName(0) == null && signature.getName(1) == null && signature.getName(2) == null && signature.getName(3) == valueArgName;
+        }
+        return false;
     }
 
     /**
      * Common code shared between specials doing subset/subscript related operation.
      */
+    @TypeSystemReference(EmptyTypeSystemFlatLayout.class)
     abstract static class SubscriptSpecialCommon extends RNode {
 
-        protected final ValueProfile vectorClassProfile = ValueProfile.createClassProfile();
+        protected final boolean inReplacement;
 
-        protected boolean isValidIndex(RAbstractVector vector, int index) {
-            vector = vectorClassProfile.profile(vector);
-            return index >= 1 && index <= vector.getLength();
+        protected SubscriptSpecialCommon(boolean inReplacement) {
+            this.inReplacement = inReplacement;
         }
 
-        protected boolean isValidDoubleIndex(RAbstractVector vector, double index) {
-            return isValidIndex(vector, toIndex(index));
+        /**
+         * Checks whether the given (1-based) index is valid for the given vector.
+         */
+        protected static boolean isValidIndex(RAbstractVector vector, int index) {
+            return index >= 1 && index <= vector.getLength();
         }
 
         /**
-         * Note: conversion from double to an index differs in subscript and subset.
+         * Checks if the value is single element that can be put into a list or vector as is,
+         * because in the case of vectors on the LSH of update we take each element and put it into
+         * the RHS of the update function.
          */
-        protected int toIndex(double index) {
-            if (index == 0) {
-                return 0;
-            }
-            int i = (int) index;
-            return i == 0 ? 1 : i;
+        protected static boolean isSingleElement(Object value) {
+            return value instanceof Integer || value instanceof Double || value instanceof Byte || value instanceof String;
         }
+    }
 
-        protected static int toIndexSubset(double index) {
-            return index == 0 ? 0 : (int) index;
+    @TypeSystemReference(EmptyTypeSystemFlatLayout.class)
+    abstract static class SubscriptSpecial2Common extends SubscriptSpecialCommon {
+
+        protected SubscriptSpecial2Common(boolean inReplacement) {
+            super(inReplacement);
+        }
+
+        @Child private GetDimAttributeNode getDimensions = GetDimAttributeNode.create();
+
+        protected int matrixIndex(RAbstractVector vector, int index1, int index2) {
+            return index1 - 1 + ((index2 - 1) * getDimensions.getDimensions(vector)[0]);
+        }
+
+        /**
+         * Checks whether the given (1-based) indexes are valid for the given matrix.
+         */
+        protected boolean isValidIndex(RAbstractVector vector, int index1, int index2) {
+            int[] dimensions = getDimensions.getDimensions(vector);
+            return dimensions != null && dimensions.length == 2 && index1 >= 1 && index1 <= dimensions[0] && index2 >= 1 && index2 <= dimensions[1];
         }
     }
 
     /**
      * Common code shared between specials accessing/updating fields.
      */
+    @TypeSystemReference(EmptyTypeSystemFlatLayout.class)
     abstract static class ListFieldSpecialBase extends RNode {
-        @CompilationFinal private String cachedField;
-        @CompilationFinal private RStringVector cachedNames;
+
         @Child private ClassHierarchyNode hierarchyNode = ClassHierarchyNode.create();
         @Child protected GetNamesAttributeNode getNamesNode = GetNamesAttributeNode.create();
 
-        protected final void updateCache(RList list, String field) {
-            if (cachedField == null) {
-                CompilerDirectives.transferToInterpreterAndInvalidate();
-                cachedField = field;
-                cachedNames = getNamesNode.getNames(list);
-            }
-        }
-
         protected final boolean isSimpleList(RList list) {
             return hierarchyNode.execute(list) == null;
         }
 
-        protected final boolean isCached(RList list, String field) {
-            return cachedField == null || (cachedField == field && getNamesNode.getNames(list) == cachedNames);
-        }
-
         protected static int getIndex(RStringVector names, String field) {
-            int fieldHash = field.hashCode();
-            for (int i = 0; i < names.getLength(); i++) {
-                String current = names.getDataAt(i);
-                if (current == field || hashCodeEquals(current, fieldHash) && contentsEquals(current, field)) {
-                    return i;
+            if (names != null) {
+                int fieldHash = field.hashCode();
+                for (int i = 0; i < names.getLength(); i++) {
+                    String current = names.getDataAt(i);
+                    if (current == field || hashCodeEquals(current, fieldHash) && contentsEquals(current, field)) {
+                        return i;
+                    }
                 }
             }
             return -1;
@@ -124,4 +149,73 @@ class SpecialsUtils {
             return current.hashCode() == fieldHash;
         }
     }
+
+    @NodeInfo(cost = NodeCost.NONE)
+    public static final class ProfiledValue extends RBaseNode {
+
+        private final ValueProfile profile = ValueProfile.createClassProfile();
+
+        @Child private RNode delegate;
+
+        protected ProfiledValue(RNode delegate) {
+            this.delegate = delegate;
+        }
+
+        public Object execute(VirtualFrame frame) {
+            return profile.profile(delegate.execute(frame));
+        }
+
+        @Override
+        protected RSyntaxNode getRSyntaxNode() {
+            return delegate.asRSyntaxNode();
+        }
+    }
+
+    @NodeInfo(cost = NodeCost.NONE)
+    @NodeChildren({@NodeChild(value = "delegate", type = RNode.class)})
+    @TypeSystemReference(EmptyTypeSystemFlatLayout.class)
+    public abstract static class ConvertIndex extends RNode {
+
+        protected abstract RNode getDelegate();
+
+        @Specialization
+        protected static int convertInteger(int value) {
+            return value;
+        }
+
+        @Specialization(rewriteOn = IllegalArgumentException.class)
+        protected int convertDouble(double value) {
+            int intValue = (int) value;
+            if (intValue == 0) {
+                /*
+                 * Conversion from double to an index differs in subscript and subset for values in
+                 * the ]0..1[ range (subscript interprets 0.1 as 1, whereas subset treats it as 0).
+                 * We avoid this special case by simply going to the more generic case for this
+                 * range. Additionally, (int) Double.NaN is 0, which is also caught by this case.
+                 */
+                CompilerDirectives.transferToInterpreterAndInvalidate();
+                throw new IllegalArgumentException();
+            } else {
+                return intValue;
+            }
+        }
+
+        @Specialization(contains = {"convertInteger", "convertDouble"})
+        protected Object convert(Object value) {
+            return value;
+        }
+
+        @Override
+        protected RSyntaxNode getRSyntaxNode() {
+            return getDelegate().asRSyntaxNode();
+        }
+    }
+
+    public static ProfiledValue profile(RNode value) {
+        return new ProfiledValue(value);
+    }
+
+    public static ConvertIndex convertIndex(RNode value) {
+        return ConvertIndexNodeGen.create(value);
+    }
 }
diff --git a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/infix/Subscript.java b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/infix/Subscript.java
index ed74d6b51b07cdd7a9495ded353dfff1c8343d90..639d98960d7c6d646e830621a8926430c80d9136 100644
--- a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/infix/Subscript.java
+++ b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/infix/Subscript.java
@@ -22,6 +22,8 @@
  */
 package com.oracle.truffle.r.nodes.builtin.base.infix;
 
+import static com.oracle.truffle.r.nodes.builtin.base.infix.SpecialsUtils.convertIndex;
+import static com.oracle.truffle.r.nodes.builtin.base.infix.SpecialsUtils.profile;
 import static com.oracle.truffle.r.runtime.RDispatch.INTERNAL_GENERIC;
 import static com.oracle.truffle.r.runtime.builtins.RBehavior.PURE;
 import static com.oracle.truffle.r.runtime.builtins.RBuiltinKind.PRIMITIVE;
@@ -29,14 +31,17 @@ import static com.oracle.truffle.r.runtime.builtins.RBuiltinKind.PRIMITIVE;
 import com.oracle.truffle.api.dsl.Cached;
 import com.oracle.truffle.api.dsl.Fallback;
 import com.oracle.truffle.api.dsl.NodeChild;
+import com.oracle.truffle.api.dsl.NodeChildren;
 import com.oracle.truffle.api.dsl.Specialization;
 import com.oracle.truffle.api.dsl.TypeSystemReference;
 import com.oracle.truffle.api.frame.VirtualFrame;
-import com.oracle.truffle.r.nodes.EmptyTypeSystemFlatLayout;
 import com.oracle.truffle.r.nodes.access.vector.ElementAccessMode;
 import com.oracle.truffle.r.nodes.access.vector.ExtractListElement;
 import com.oracle.truffle.r.nodes.access.vector.ExtractVectorNode;
 import com.oracle.truffle.r.nodes.builtin.RBuiltinNode;
+import com.oracle.truffle.r.nodes.builtin.base.infix.SpecialsUtils.ConvertIndex;
+import com.oracle.truffle.r.nodes.builtin.base.infix.SpecialsUtils.ProfiledValue;
+import com.oracle.truffle.r.nodes.builtin.base.infix.SpecialsUtils.SubscriptSpecial2Common;
 import com.oracle.truffle.r.nodes.builtin.base.infix.SpecialsUtils.SubscriptSpecialCommon;
 import com.oracle.truffle.r.nodes.function.ClassHierarchyNode;
 import com.oracle.truffle.r.nodes.function.ClassHierarchyNodeGen;
@@ -50,6 +55,7 @@ import com.oracle.truffle.r.runtime.data.RList;
 import com.oracle.truffle.r.runtime.data.RLogical;
 import com.oracle.truffle.r.runtime.data.RMissing;
 import com.oracle.truffle.r.runtime.data.RNull;
+import com.oracle.truffle.r.runtime.data.RTypesFlatLayout;
 import com.oracle.truffle.r.runtime.data.model.RAbstractDoubleVector;
 import com.oracle.truffle.r.runtime.data.model.RAbstractIntVector;
 import com.oracle.truffle.r.runtime.data.model.RAbstractLogicalVector;
@@ -60,10 +66,13 @@ import com.oracle.truffle.r.runtime.nodes.RNode;
 /**
  * Subscript code for vectors minus list is the same as subset code, this class allows sharing it.
  */
-@NodeChild(value = "arguments", type = RNode[].class)
-@TypeSystemReference(EmptyTypeSystemFlatLayout.class)
+@NodeChildren({@NodeChild(value = "vector", type = ProfiledValue.class), @NodeChild(value = "index", type = ConvertIndex.class)})
 abstract class SubscriptSpecialBase extends SubscriptSpecialCommon {
 
+    protected SubscriptSpecialBase(boolean inReplacement) {
+        super(inReplacement);
+    }
+
     @Child private ClassHierarchyNode classHierarchy = ClassHierarchyNodeGen.create(false, false);
 
     protected boolean simpleVector(RAbstractVector vector) {
@@ -72,58 +81,108 @@ abstract class SubscriptSpecialBase extends SubscriptSpecialCommon {
 
     @Specialization(guards = {"simpleVector(vector)", "isValidIndex(vector, index)"})
     protected int access(RAbstractIntVector vector, int index) {
-        return vectorClassProfile.profile(vector).getDataAt(index - 1);
+        return vector.getDataAt(index - 1);
     }
 
     @Specialization(guards = {"simpleVector(vector)", "isValidIndex(vector, index)"})
     protected double access(RAbstractDoubleVector vector, int index) {
-        return vectorClassProfile.profile(vector).getDataAt(index - 1);
+        return vector.getDataAt(index - 1);
     }
 
     @Specialization(guards = {"simpleVector(vector)", "isValidIndex(vector, index)"})
     protected String access(RAbstractStringVector vector, int index) {
-        return vectorClassProfile.profile(vector).getDataAt(index - 1);
+        return vector.getDataAt(index - 1);
     }
 
-    @Specialization(guards = {"simpleVector(vector)", "isValidDoubleIndex(vector, index)"})
-    protected int access(RAbstractIntVector vector, double index) {
-        return vectorClassProfile.profile(vector).getDataAt(toIndex(index) - 1);
+    @SuppressWarnings("unused")
+    @Fallback
+    protected static Object access(Object vector, Object index) {
+        throw RSpecialFactory.throwFullCallNeeded();
     }
+}
+
+/**
+ * Subscript code for matrices minus list is the same as subset code, this class allows sharing it.
+ */
+@NodeChildren({@NodeChild(value = "vector", type = ProfiledValue.class), @NodeChild(value = "index1", type = ConvertIndex.class), @NodeChild(value = "index2", type = ConvertIndex.class)})
+abstract class SubscriptSpecial2Base extends SubscriptSpecial2Common {
 
-    @Specialization(guards = {"simpleVector(vector)", "isValidDoubleIndex(vector, index)"})
-    protected double access(RAbstractDoubleVector vector, double index) {
-        return vectorClassProfile.profile(vector).getDataAt(toIndex(index) - 1);
+    protected SubscriptSpecial2Base(boolean inReplacement) {
+        super(inReplacement);
     }
 
-    @Specialization(guards = {"simpleVector(vector)", "isValidDoubleIndex(vector, index)"})
-    protected String access(RAbstractStringVector vector, double index) {
-        return vectorClassProfile.profile(vector).getDataAt(toIndex(index) - 1);
+    @Child private ClassHierarchyNode classHierarchy = ClassHierarchyNodeGen.create(false, false);
+
+    protected abstract ProfiledValue getVector();
+
+    protected abstract ConvertIndex getIndex1();
+
+    protected abstract ConvertIndex getIndex2();
+
+    protected boolean simpleVector(RAbstractVector vector) {
+        return classHierarchy.execute(vector) == null;
+    }
+
+    @Specialization(guards = {"simpleVector(vector)", "isValidIndex(vector, index1, index2)"})
+    protected int access(RAbstractIntVector vector, int index1, int index2) {
+        return vector.getDataAt(matrixIndex(vector, index1, index2));
+    }
+
+    @Specialization(guards = {"simpleVector(vector)", "isValidIndex(vector, index1, index2)"})
+    protected double access(RAbstractDoubleVector vector, int index1, int index2) {
+        return vector.getDataAt(matrixIndex(vector, index1, index2));
+    }
+
+    @Specialization(guards = {"simpleVector(vector)", "isValidIndex(vector, index1, index2)"})
+    protected String access(RAbstractStringVector vector, int index1, int index2) {
+        return vector.getDataAt(matrixIndex(vector, index1, index2));
     }
 
     @SuppressWarnings("unused")
     @Fallback
-    protected static Object access(Object vector, Object index) {
+    protected static Object access(Object vector, Object index1, Object index2) {
         throw RSpecialFactory.throwFullCallNeeded();
     }
 }
 
-@TypeSystemReference(EmptyTypeSystemFlatLayout.class)
 abstract class SubscriptSpecial extends SubscriptSpecialBase {
 
-    @Specialization(guards = {"simpleVector(vector)", "isValidIndex(vector, index)"})
+    protected SubscriptSpecial(boolean inReplacement) {
+        super(inReplacement);
+    }
+
+    @Specialization(guards = {"simpleVector(vector)", "isValidIndex(vector, index)", "!inReplacement"})
     protected static Object access(RList vector, int index,
                     @Cached("create()") ExtractListElement extract) {
         return extract.execute(vector, index - 1);
     }
 
-    @Specialization(guards = {"simpleVector(vector)", "isValidDoubleIndex(vector, index)"})
-    protected Object access(RList vector, double index,
+    protected static ExtractVectorNode createAccess() {
+        return ExtractVectorNode.create(ElementAccessMode.SUBSCRIPT, false);
+    }
+
+    @Specialization(guards = {"simpleVector(vector)", "!inReplacement"})
+    protected static Object access(VirtualFrame frame, RAbstractVector vector, Object index,
+                    @Cached("createAccess()") ExtractVectorNode extract) {
+        return extract.apply(frame, vector, new Object[]{index}, RRuntime.LOGICAL_TRUE, RLogical.TRUE);
+    }
+}
+
+abstract class SubscriptSpecial2 extends SubscriptSpecial2Base {
+
+    protected SubscriptSpecial2(boolean inReplacement) {
+        super(inReplacement);
+    }
+
+    @Specialization(guards = {"simpleVector(vector)", "isValidIndex(vector, index1, index2)", "!inReplacement"})
+    protected Object access(RList vector, int index1, int index2,
                     @Cached("create()") ExtractListElement extract) {
-        return extract.execute(vector, toIndex(index) - 1);
+        return extract.execute(vector, matrixIndex(vector, index1, index2));
     }
 }
 
 @RBuiltin(name = "[[", kind = PRIMITIVE, parameterNames = {"x", "...", "exact", "drop"}, dispatch = INTERNAL_GENERIC, behavior = PURE)
+@TypeSystemReference(RTypesFlatLayout.class)
 public abstract class Subscript extends RBuiltinNode {
 
     @RBuiltin(name = ".subset2", kind = PRIMITIVE, parameterNames = {"x", "...", "exact", "drop"}, behavior = PURE)
@@ -131,8 +190,15 @@ public abstract class Subscript extends RBuiltinNode {
         // same implementation as "[[", with different dispatch
     }
 
-    public static RNode special(ArgumentsSignature signature, RNode[] arguments, @SuppressWarnings("unused") boolean inReplacement) {
-        return signature.getNonNullCount() == 0 && arguments.length == 2 ? SubscriptSpecialNodeGen.create(arguments) : null;
+    public static RNode special(ArgumentsSignature signature, RNode[] arguments, boolean inReplacement) {
+        if (signature.getNonNullCount() == 0) {
+            if (arguments.length == 2) {
+                return SubscriptSpecialNodeGen.create(inReplacement, profile(arguments[0]), convertIndex(arguments[1]));
+            } else if (arguments.length == 3) {
+                return SubscriptSpecial2NodeGen.create(inReplacement, profile(arguments[0]), convertIndex(arguments[1]), convertIndex(arguments[2]));
+            }
+        }
+        return null;
     }
 
     @Child private ExtractVectorNode extractNode = ExtractVectorNode.create(ElementAccessMode.SUBSCRIPT, false);
diff --git a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/infix/Subset.java b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/infix/Subset.java
index 9d693de22845ef0dba043d41824103eeda08015e..b36cbf5a3e24f4d056b0d5a8de2a166d631cd83d 100644
--- a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/infix/Subset.java
+++ b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/infix/Subset.java
@@ -22,6 +22,8 @@
  */
 package com.oracle.truffle.r.nodes.builtin.base.infix;
 
+import static com.oracle.truffle.r.nodes.builtin.base.infix.SpecialsUtils.convertIndex;
+import static com.oracle.truffle.r.nodes.builtin.base.infix.SpecialsUtils.profile;
 import static com.oracle.truffle.r.runtime.RDispatch.INTERNAL_GENERIC;
 import static com.oracle.truffle.r.runtime.builtins.RBehavior.PURE;
 import static com.oracle.truffle.r.runtime.builtins.RBuiltinKind.PRIMITIVE;
@@ -37,7 +39,10 @@ import com.oracle.truffle.r.nodes.access.vector.ExtractVectorNode;
 import com.oracle.truffle.r.nodes.attributes.SpecialAttributesFunctions.GetNamesAttributeNode;
 import com.oracle.truffle.r.nodes.builtin.CastBuilder;
 import com.oracle.truffle.r.nodes.builtin.RBuiltinNode;
+import com.oracle.truffle.r.nodes.builtin.base.infix.SpecialsUtils.ConvertIndex;
+import com.oracle.truffle.r.nodes.builtin.base.infix.SpecialsUtils.ProfiledValue;
 import com.oracle.truffle.r.runtime.ArgumentsSignature;
+import com.oracle.truffle.r.runtime.RRuntime;
 import com.oracle.truffle.r.runtime.builtins.RBuiltin;
 import com.oracle.truffle.r.runtime.data.RArgsValuesAndNames;
 import com.oracle.truffle.r.runtime.data.RDataFactory;
@@ -52,36 +57,63 @@ import com.oracle.truffle.r.runtime.nodes.RNode;
  * Subset special only handles single element integer/double index. In the case of list, we need to
  * create the actual list otherwise we just return the primitive type.
  */
-@TypeSystemReference(EmptyTypeSystemFlatLayout.class)
 abstract class SubsetSpecial extends SubscriptSpecialBase {
 
     @Child private GetNamesAttributeNode getNamesNode = GetNamesAttributeNode.create();
 
-    @Override
-    protected boolean simpleVector(RAbstractVector vector) {
-        vector = vectorClassProfile.profile(vector);
-        return super.simpleVector(vector) && getNamesNode.getNames(vector) == null;
+    protected SubsetSpecial(boolean inReplacement) {
+        super(inReplacement);
     }
 
     @Override
-    protected int toIndex(double index) {
-        return toIndexSubset(index);
+    protected boolean simpleVector(RAbstractVector vector) {
+        return super.simpleVector(vector) && getNamesNode.getNames(vector) == null;
     }
 
-    @Specialization(guards = {"simpleVector(vector)", "isValidIndex(vector, index)"})
+    @Specialization(guards = {"simpleVector(vector)", "isValidIndex(vector, index)", "!inReplacement"})
     protected static RList access(RList vector, int index,
                     @Cached("create()") ExtractListElement extract) {
         return RDataFactory.createList(new Object[]{extract.execute(vector, index - 1)});
     }
 
-    @Specialization(guards = {"simpleVector(vector)", "isValidDoubleIndex(vector, index)"})
-    protected static RList access(RList vector, double index,
+    protected static ExtractVectorNode createAccess() {
+        return ExtractVectorNode.create(ElementAccessMode.SUBSET, false);
+    }
+
+    @Specialization(guards = {"simpleVector(vector)", "!inReplacement"})
+    protected Object access(VirtualFrame frame, RAbstractVector vector, Object index,
+                    @Cached("createAccess()") ExtractVectorNode extract) {
+        return extract.apply(frame, vector, new Object[]{index}, RRuntime.LOGICAL_TRUE, RLogical.TRUE);
+    }
+}
+
+/**
+ * Subset special only handles single element integer/double index. In the case of list, we need to
+ * create the actual list otherwise we just return the primitive type.
+ */
+@TypeSystemReference(EmptyTypeSystemFlatLayout.class)
+abstract class SubsetSpecial2 extends SubscriptSpecial2Base {
+
+    @Child private GetNamesAttributeNode getNamesNode = GetNamesAttributeNode.create();
+
+    protected SubsetSpecial2(boolean inReplacement) {
+        super(inReplacement);
+    }
+
+    @Override
+    protected boolean simpleVector(RAbstractVector vector) {
+        return super.simpleVector(vector) && getNamesNode.getNames(vector) == null;
+    }
+
+    @Specialization(guards = {"simpleVector(vector)", "isValidIndex(vector, index1, index2)", "!inReplacement"})
+    protected RList access(RList vector, int index1, int index2,
                     @Cached("create()") ExtractListElement extract) {
-        return RDataFactory.createList(new Object[]{extract.execute(vector, toIndexSubset(index) - 1)});
+        return RDataFactory.createList(new Object[]{extract.execute(vector, matrixIndex(vector, index1, index2))});
     }
 }
 
 @RBuiltin(name = "[", kind = PRIMITIVE, parameterNames = {"x", "...", "drop"}, dispatch = INTERNAL_GENERIC, behavior = PURE)
+@TypeSystemReference(EmptyTypeSystemFlatLayout.class)
 public abstract class Subset extends RBuiltinNode {
 
     @RBuiltin(name = ".subset", kind = PRIMITIVE, parameterNames = {"", "...", "drop"}, behavior = PURE)
@@ -89,14 +121,17 @@ public abstract class Subset extends RBuiltinNode {
         // same implementation as "[", with different dispatch
     }
 
-    public static RNode special(ArgumentsSignature signature, RNode[] arguments, boolean inReplacement) {
-        boolean correctSignature = signature.getNonNullCount() == 0 && arguments.length == 2;
-        if (!correctSignature) {
-            return null;
+    public static RNode special(ArgumentsSignature signature, RNode[] args, boolean inReplacement) {
+        if (signature.getNonNullCount() == 0 && (args.length == 2 || args.length == 3)) {
+            ProfiledValue profiledVector = profile(args[0]);
+            ConvertIndex index = convertIndex(args[1]);
+            if (args.length == 2) {
+                return SubsetSpecialNodeGen.create(inReplacement, profiledVector, index);
+            } else {
+                return SubsetSpecial2NodeGen.create(inReplacement, profiledVector, index, convertIndex(args[2]));
+            }
         }
-        // Subset adds support for lists returning newly created list, which cannot work when used
-        // in replacement, because we need the reference to the existing (materialized) list element
-        return inReplacement ? SubscriptSpecialBaseNodeGen.create(arguments) : SubsetSpecialNodeGen.create(arguments);
+        return null;
     }
 
     @Child private ExtractVectorNode extractNode = ExtractVectorNode.create(ElementAccessMode.SUBSET, false);
diff --git a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/infix/Tilde.java b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/infix/Tilde.java
index 1918c7c7447a23370355b722e6bcf4ba139faeb0..aa565195905cc4af852dcf237e0dfbf9e6d2adaf 100644
--- a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/infix/Tilde.java
+++ b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/infix/Tilde.java
@@ -27,7 +27,9 @@ import static com.oracle.truffle.r.runtime.builtins.RBuiltinKind.PRIMITIVE;
 
 import com.oracle.truffle.api.dsl.Cached;
 import com.oracle.truffle.api.dsl.Specialization;
+import com.oracle.truffle.api.dsl.TypeSystemReference;
 import com.oracle.truffle.api.frame.VirtualFrame;
+import com.oracle.truffle.r.nodes.EmptyTypeSystemFlatLayout;
 import com.oracle.truffle.r.nodes.attributes.SetFixedAttributeNode;
 import com.oracle.truffle.r.nodes.attributes.SpecialAttributesFunctions.SetClassAttributeNode;
 import com.oracle.truffle.r.nodes.builtin.RBuiltinNode;
@@ -48,6 +50,7 @@ import com.oracle.truffle.r.runtime.nodes.RBaseNode;
  * argument is missing, i.e. {@code ~ x} result in {@code `~`(x)}.
  */
 @RBuiltin(name = "~", kind = PRIMITIVE, parameterNames = {"x", "y"}, nonEvalArgs = {0, 1}, behavior = READS_FRAME)
+@TypeSystemReference(EmptyTypeSystemFlatLayout.class)
 public abstract class Tilde extends RBuiltinNode {
 
     private static final RStringVector FORMULA_CLASS = RDataFactory.createStringVectorFromScalar(RRuntime.FORMULA_CLASS);
diff --git a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/infix/UpdateField.java b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/infix/UpdateField.java
index ebbd01a056c1e63bb5e0436186690bb062b07a2c..edb89de721d58a14448121bc9a634559c5c12258 100644
--- a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/infix/UpdateField.java
+++ b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/infix/UpdateField.java
@@ -32,8 +32,10 @@ import com.oracle.truffle.api.dsl.Cached;
 import com.oracle.truffle.api.dsl.Fallback;
 import com.oracle.truffle.api.dsl.NodeChild;
 import com.oracle.truffle.api.dsl.Specialization;
+import com.oracle.truffle.api.dsl.TypeSystemReference;
 import com.oracle.truffle.api.frame.VirtualFrame;
 import com.oracle.truffle.api.profiles.ConditionProfile;
+import com.oracle.truffle.r.nodes.EmptyTypeSystemFlatLayout;
 import com.oracle.truffle.r.nodes.access.vector.ElementAccessMode;
 import com.oracle.truffle.r.nodes.access.vector.ReplaceVectorNode;
 import com.oracle.truffle.r.nodes.builtin.CastBuilder;
@@ -48,6 +50,7 @@ import com.oracle.truffle.r.runtime.builtins.RBuiltin;
 import com.oracle.truffle.r.runtime.builtins.RSpecialFactory;
 import com.oracle.truffle.r.runtime.data.RList;
 import com.oracle.truffle.r.runtime.data.RNull;
+import com.oracle.truffle.r.runtime.data.RStringVector;
 import com.oracle.truffle.r.runtime.data.model.RAbstractListVector;
 import com.oracle.truffle.r.runtime.data.model.RAbstractVector;
 import com.oracle.truffle.r.runtime.nodes.RNode;
@@ -65,13 +68,14 @@ abstract class UpdateFieldSpecial extends SpecialsUtils.ListFieldSpecialBase {
         return value != RNull.instance && !(value instanceof RList);
     }
 
-    @Specialization(guards = {"isSimpleList(list)", "!list.isShared()", "isCached(list, field)", "list.getNames() != null", "isNotRNullRList(value)"})
-    public RList doList(RList list, String field, Object value,
-                    @Cached("getIndex(list.getNames(), field)") int index) {
+    @Specialization(limit = "2", guards = {"isSimpleList(list)", "!list.isShared()", "list.getNames() == cachedNames", "field == cachedField", "isNotRNullRList(value)"})
+    public Object doList(RList list, @SuppressWarnings("unused") String field, Object value,
+                    @SuppressWarnings("unused") @Cached("list.getNames()") RStringVector cachedNames,
+                    @SuppressWarnings("unused") @Cached("field") String cachedField,
+                    @Cached("getIndex(cachedNames, field)") int index) {
         if (index == -1) {
             throw RSpecialFactory.throwFullCallNeeded(value);
         }
-        updateCache(list, field);
         Object sharedValue = value;
         // share only when necessary:
         if (list.getDataAt(index) != value) {
@@ -83,7 +87,17 @@ abstract class UpdateFieldSpecial extends SpecialsUtils.ListFieldSpecialBase {
 
     @Specialization(contains = "doList", guards = {"isSimpleList(list)", "!list.isShared()", "list.getNames() != null", "isNotRNullRList(value)"})
     public RList doListDynamic(RList list, String field, Object value) {
-        return doList(list, field, value, getIndex(getNamesNode.getNames(list), field));
+        int index = getIndex(getNamesNode.getNames(list), field);
+        if (index == -1) {
+            throw RSpecialFactory.throwFullCallNeeded(value);
+        }
+        Object sharedValue = value;
+        // share only when necessary:
+        if (list.getDataAt(index) != value) {
+            sharedValue = getShareObjectNode().execute(value);
+        }
+        list.setElement(index, sharedValue);
+        return list;
     }
 
     @SuppressWarnings("unused")
@@ -102,9 +116,10 @@ abstract class UpdateFieldSpecial extends SpecialsUtils.ListFieldSpecialBase {
 }
 
 @RBuiltin(name = "$<-", kind = PRIMITIVE, parameterNames = {"", "", "value"}, dispatch = INTERNAL_GENERIC, behavior = PURE)
+@TypeSystemReference(EmptyTypeSystemFlatLayout.class)
 public abstract class UpdateField extends RBuiltinNode {
 
-    @Child private ReplaceVectorNode extract = ReplaceVectorNode.create(ElementAccessMode.SUBSCRIPT, true);
+    @Child private ReplaceVectorNode update = ReplaceVectorNode.create(ElementAccessMode.SUBSCRIPT, true);
     @Child private CastListNode castList;
 
     private final ConditionProfile coerceList = ConditionProfile.createBinaryProfile();
@@ -121,7 +136,7 @@ public abstract class UpdateField extends RBuiltinNode {
     @Specialization
     protected Object update(VirtualFrame frame, Object container, String field, Object value) {
         Object list = coerceList.profile(container instanceof RAbstractListVector) ? container : coerceList(container);
-        return extract.apply(frame, list, new Object[]{field}, value);
+        return update.apply(frame, list, new Object[]{field}, value);
     }
 
     private Object coerceList(Object vector) {
diff --git a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/infix/UpdateSubscript.java b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/infix/UpdateSubscript.java
index 5a68b3998b0e09edf9ddc0c2374f005f7b0675f9..1488822ff52f5d2ecad17d08cfad470af6f3ad33 100644
--- a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/infix/UpdateSubscript.java
+++ b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/infix/UpdateSubscript.java
@@ -22,6 +22,8 @@
  */
 package com.oracle.truffle.r.nodes.builtin.base.infix;
 
+import static com.oracle.truffle.r.nodes.builtin.base.infix.SpecialsUtils.convertIndex;
+import static com.oracle.truffle.r.nodes.builtin.base.infix.SpecialsUtils.profile;
 import static com.oracle.truffle.r.runtime.RDispatch.INTERNAL_GENERIC;
 import static com.oracle.truffle.r.runtime.builtins.RBehavior.PURE;
 import static com.oracle.truffle.r.runtime.builtins.RBuiltinKind.PRIMITIVE;
@@ -30,6 +32,7 @@ import java.util.Arrays;
 
 import com.oracle.truffle.api.dsl.Fallback;
 import com.oracle.truffle.api.dsl.NodeChild;
+import com.oracle.truffle.api.dsl.NodeChildren;
 import com.oracle.truffle.api.dsl.Specialization;
 import com.oracle.truffle.api.dsl.TypeSystemReference;
 import com.oracle.truffle.api.frame.VirtualFrame;
@@ -38,6 +41,9 @@ import com.oracle.truffle.r.nodes.EmptyTypeSystemFlatLayout;
 import com.oracle.truffle.r.nodes.access.vector.ElementAccessMode;
 import com.oracle.truffle.r.nodes.access.vector.ReplaceVectorNode;
 import com.oracle.truffle.r.nodes.builtin.RBuiltinNode;
+import com.oracle.truffle.r.nodes.builtin.base.infix.SpecialsUtils.ConvertIndex;
+import com.oracle.truffle.r.nodes.builtin.base.infix.SpecialsUtils.ProfiledValue;
+import com.oracle.truffle.r.nodes.builtin.base.infix.SpecialsUtils.SubscriptSpecial2Common;
 import com.oracle.truffle.r.nodes.builtin.base.infix.SpecialsUtils.SubscriptSpecialCommon;
 import com.oracle.truffle.r.nodes.function.ClassHierarchyNode;
 import com.oracle.truffle.r.nodes.function.ClassHierarchyNodeGen;
@@ -54,25 +60,21 @@ import com.oracle.truffle.r.runtime.data.RStringVector;
 import com.oracle.truffle.r.runtime.nodes.RNode;
 import com.oracle.truffle.r.runtime.ops.na.NACheck;
 
-@NodeChild(value = "arguments", type = RNode[].class)
-@TypeSystemReference(EmptyTypeSystemFlatLayout.class)
+@NodeChildren({@NodeChild(value = "vector", type = ProfiledValue.class), @NodeChild(value = "index", type = ConvertIndex.class), @NodeChild(value = "value", type = RNode.class)})
 abstract class UpdateSubscriptSpecial extends SubscriptSpecialCommon {
+
+    protected UpdateSubscriptSpecial(boolean inReplacement) {
+        super(inReplacement);
+    }
+
     @Child private ClassHierarchyNode classHierarchy = ClassHierarchyNodeGen.create(false, false);
+
     private final NACheck naCheck = NACheck.create();
 
     protected boolean simple(Object vector) {
         return classHierarchy.execute(vector) == null;
     }
 
-    /**
-     * Checks if the value is single element that can be put into a list or vector as is, because in
-     * the case of vectors on the LSH of update we take each element and put it into the RHS of the
-     * update function.
-     */
-    protected static boolean isSingleElement(Object value) {
-        return value instanceof Integer || value instanceof Double || value instanceof Byte || value instanceof String;
-    }
-
     @Specialization(guards = {"simple(vector)", "!vector.isShared()", "isValidIndex(vector, index)"})
     protected RIntVector set(RIntVector vector, int index, int value) {
         return vector.updateDataAt(index - 1, value, naCheck);
@@ -94,53 +96,86 @@ abstract class UpdateSubscriptSpecial extends SubscriptSpecialCommon {
         return list;
     }
 
-    @Specialization(guards = {"simple(vector)", "!vector.isShared()", "isValidDoubleIndex(vector, index)"})
-    protected RIntVector setDoubleIndex(RIntVector vector, double index, int value) {
-        return vector.updateDataAt(toIndex(index) - 1, value, naCheck);
-    }
-
     @Specialization(guards = {"simple(vector)", "!vector.isShared()", "isValidIndex(vector, index)"})
     protected RDoubleVector setDoubleIntIndexIntValue(RDoubleVector vector, int index, int value) {
-        return vector.updateDataAt(toIndex(index) - 1, value, naCheck);
+        return vector.updateDataAt(index - 1, value, naCheck);
     }
 
-    @Specialization(guards = {"simple(vector)", "!vector.isShared()", "isValidDoubleIndex(vector, index)"})
-    protected RDoubleVector setDoubleIndexIntValue(RDoubleVector vector, double index, int value) {
-        return vector.updateDataAt(toIndex(index) - 1, value, naCheck);
+    @SuppressWarnings("unused")
+    @Fallback
+    protected static Object setFallback(Object vector, Object index, Object value) {
+        throw RSpecialFactory.throwFullCallNeeded(value);
     }
+}
 
-    @Specialization(guards = {"simple(vector)", "!vector.isShared()", "isValidDoubleIndex(vector, index)"})
-    protected RDoubleVector setDoubleIndex(RDoubleVector vector, double index, double value) {
-        return vector.updateDataAt(toIndex(index) - 1, value, naCheck);
+@NodeChildren({@NodeChild(value = "vector", type = ProfiledValue.class), @NodeChild(value = "index1", type = ConvertIndex.class), @NodeChild(value = "index2", type = ConvertIndex.class),
+                @NodeChild(value = "value", type = RNode.class)})
+abstract class UpdateSubscriptSpecial2 extends SubscriptSpecial2Common {
+
+    protected UpdateSubscriptSpecial2(boolean inReplacement) {
+        super(inReplacement);
     }
 
-    @Specialization(guards = {"simple(vector)", "!vector.isShared()", "isValidDoubleIndex(vector, index)"})
-    protected RStringVector setDoubleIndex(RStringVector vector, double index, String value) {
-        return vector.updateDataAt(toIndex(index) - 1, value, naCheck);
+    @Child private ClassHierarchyNode classHierarchy = ClassHierarchyNodeGen.create(false, false);
+
+    private final NACheck naCheck = NACheck.create();
+
+    protected boolean simple(Object vector) {
+        return classHierarchy.execute(vector) == null;
+    }
+
+    @Specialization(guards = {"simple(vector)", "!vector.isShared()", "isValidIndex(vector, index1, index2)"})
+    protected RIntVector set(RIntVector vector, int index1, int index2, int value) {
+        return vector.updateDataAt(matrixIndex(vector, index1, index2), value, naCheck);
+    }
+
+    @Specialization(guards = {"simple(vector)", "!vector.isShared()", "isValidIndex(vector, index1, index2)"})
+    protected RDoubleVector set(RDoubleVector vector, int index1, int index2, double value) {
+        return vector.updateDataAt(matrixIndex(vector, index1, index2), value, naCheck);
+    }
+
+    @Specialization(guards = {"simple(vector)", "!vector.isShared()", "isValidIndex(vector, index1, index2)"})
+    protected RStringVector set(RStringVector vector, int index1, int index2, String value) {
+        return vector.updateDataAt(matrixIndex(vector, index1, index2), value, naCheck);
     }
 
-    @Specialization(guards = {"simple(list)", "!list.isShared()", "isValidDoubleIndex(list, index)", "isSingleElement(value)"})
-    protected Object setDoubleIndex(RList list, double index, Object value) {
-        list.setDataAt(list.getInternalStore(), toIndex(index) - 1, value);
+    @Specialization(guards = {"simple(list)", "!list.isShared()", "isValidIndex(list, index1, index2)", "isSingleElement(value)"})
+    protected Object set(RList list, int index1, int index2, Object value) {
+        list.setDataAt(list.getInternalStore(), matrixIndex(list, index1, index2), value);
         return list;
     }
 
+    @Specialization(guards = {"simple(vector)", "!vector.isShared()", "isValidIndex(vector, index1, index2)"})
+    protected RDoubleVector setDoubleIntIndexIntValue(RDoubleVector vector, int index1, int index2, int value) {
+        return vector.updateDataAt(matrixIndex(vector, index1, index2), value, naCheck);
+    }
+
     @SuppressWarnings("unused")
     @Fallback
-    protected static Object setFallback(Object vector, Object index, Object value) {
+    protected static Object setFallback(Object vector, Object index1, Object index2, Object value) {
         throw RSpecialFactory.throwFullCallNeeded(value);
     }
 }
 
 @RBuiltin(name = "[[<-", kind = PRIMITIVE, parameterNames = {"", "..."}, dispatch = INTERNAL_GENERIC, behavior = PURE)
+@TypeSystemReference(EmptyTypeSystemFlatLayout.class)
 public abstract class UpdateSubscript extends RBuiltinNode {
 
     @Child private ReplaceVectorNode replaceNode = ReplaceVectorNode.create(ElementAccessMode.SUBSCRIPT, false);
 
     private final ConditionProfile argsLengthLargerThanOneProfile = ConditionProfile.createBinaryProfile();
 
-    public static RNode special(ArgumentsSignature signature, RNode[] arguments, @SuppressWarnings("unused") boolean inReplacement) {
-        return SpecialsUtils.isCorrectUpdateSignature(signature) && arguments.length == 3 ? UpdateSubscriptSpecialNodeGen.create(arguments) : null;
+    public static RNode special(ArgumentsSignature signature, RNode[] args, boolean inReplacement) {
+        if (SpecialsUtils.isCorrectUpdateSignature(signature) && (args.length == 3 || args.length == 4)) {
+            ProfiledValue vector = profile(args[0]);
+            ConvertIndex index = convertIndex(args[1]);
+            if (args.length == 3) {
+                return UpdateSubscriptSpecialNodeGen.create(inReplacement, vector, index, args[2]);
+            } else {
+                return UpdateSubscriptSpecial2NodeGen.create(inReplacement, vector, index, convertIndex(args[2]), args[3]);
+            }
+        }
+        return null;
     }
 
     @Specialization(guards = "!args.isEmpty()")
diff --git a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/infix/UpdateSubset.java b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/infix/UpdateSubset.java
index 5c92d85bf3ca0df6b123e20f9cec2b15573b631a..4e9fd8094a382c3eb0695c56baa8cce51cd91a4a 100644
--- a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/infix/UpdateSubset.java
+++ b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/infix/UpdateSubset.java
@@ -22,13 +22,14 @@
  */
 package com.oracle.truffle.r.nodes.builtin.base.infix;
 
+import static com.oracle.truffle.r.nodes.builtin.base.infix.SpecialsUtils.convertIndex;
+import static com.oracle.truffle.r.nodes.builtin.base.infix.SpecialsUtils.profile;
 import static com.oracle.truffle.r.runtime.RDispatch.INTERNAL_GENERIC;
 import static com.oracle.truffle.r.runtime.builtins.RBehavior.PURE;
 import static com.oracle.truffle.r.runtime.builtins.RBuiltinKind.PRIMITIVE;
 
 import java.util.Arrays;
 
-import com.oracle.truffle.api.dsl.NodeChild;
 import com.oracle.truffle.api.dsl.Specialization;
 import com.oracle.truffle.api.dsl.TypeSystemReference;
 import com.oracle.truffle.api.frame.VirtualFrame;
@@ -37,6 +38,8 @@ import com.oracle.truffle.r.nodes.EmptyTypeSystemFlatLayout;
 import com.oracle.truffle.r.nodes.access.vector.ElementAccessMode;
 import com.oracle.truffle.r.nodes.access.vector.ReplaceVectorNode;
 import com.oracle.truffle.r.nodes.builtin.RBuiltinNode;
+import com.oracle.truffle.r.nodes.builtin.base.infix.SpecialsUtils.ConvertIndex;
+import com.oracle.truffle.r.nodes.builtin.base.infix.SpecialsUtils.ProfiledValue;
 import com.oracle.truffle.r.runtime.ArgumentsSignature;
 import com.oracle.truffle.r.runtime.RError;
 import com.oracle.truffle.r.runtime.builtins.RBuiltin;
@@ -44,24 +47,24 @@ import com.oracle.truffle.r.runtime.data.RArgsValuesAndNames;
 import com.oracle.truffle.r.runtime.data.RMissing;
 import com.oracle.truffle.r.runtime.nodes.RNode;
 
-@NodeChild(value = "arguments", type = RNode[].class)
-@TypeSystemReference(EmptyTypeSystemFlatLayout.class)
-abstract class UpdateSubsetSpecial extends UpdateSubscriptSpecial {
-
-    @Override
-    protected int toIndex(double index) {
-        return toIndexSubset(index);
-    }
-}
-
 @RBuiltin(name = "[<-", kind = PRIMITIVE, parameterNames = {"", "..."}, dispatch = INTERNAL_GENERIC, behavior = PURE)
+@TypeSystemReference(EmptyTypeSystemFlatLayout.class)
 public abstract class UpdateSubset extends RBuiltinNode {
 
     @Child private ReplaceVectorNode replaceNode = ReplaceVectorNode.create(ElementAccessMode.SUBSET, false);
     private final ConditionProfile argsLengthLargerThanOneProfile = ConditionProfile.createBinaryProfile();
 
-    public static RNode special(ArgumentsSignature signature, RNode[] arguments, @SuppressWarnings("unused") boolean inReplacement) {
-        return SpecialsUtils.isCorrectUpdateSignature(signature) && arguments.length == 3 ? UpdateSubsetSpecialNodeGen.create(arguments) : null;
+    public static RNode special(ArgumentsSignature signature, RNode[] args, boolean inReplacement) {
+        if (SpecialsUtils.isCorrectUpdateSignature(signature) && (args.length == 3 || args.length == 4)) {
+            ProfiledValue vector = profile(args[0]);
+            ConvertIndex index = convertIndex(args[1]);
+            if (args.length == 3) {
+                return UpdateSubscriptSpecialNodeGen.create(inReplacement, vector, index, args[2]);
+            } else {
+                return UpdateSubscriptSpecial2NodeGen.create(inReplacement, vector, index, convertIndex(args[2]), args[3]);
+            }
+        }
+        return null;
     }
 
     @Specialization(guards = "!args.isEmpty()")
diff --git a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/fastr/FastRInterop.java b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/fastr/FastRInterop.java
index ce5c3dae4dc188754d89052895ff69e884dd5d6c..f0a1eaaf6eadefcfdc832fa191210af6fe13681e 100644
--- a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/fastr/FastRInterop.java
+++ b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/fastr/FastRInterop.java
@@ -31,6 +31,9 @@ import static com.oracle.truffle.r.runtime.RVisibility.ON;
 import static com.oracle.truffle.r.runtime.builtins.RBehavior.COMPLEX;
 import static com.oracle.truffle.r.runtime.builtins.RBuiltinKind.PRIMITIVE;
 
+import java.io.File;
+import java.io.IOException;
+
 import com.oracle.truffle.api.CallTarget;
 import com.oracle.truffle.api.CompilerAsserts;
 import com.oracle.truffle.api.CompilerDirectives.TruffleBoundary;
@@ -44,6 +47,7 @@ import com.oracle.truffle.api.interop.TruffleObject;
 import com.oracle.truffle.api.nodes.DirectCallNode;
 import com.oracle.truffle.api.nodes.Node;
 import com.oracle.truffle.api.source.Source;
+import com.oracle.truffle.api.source.Source.Builder;
 import com.oracle.truffle.r.nodes.builtin.CastBuilder;
 import com.oracle.truffle.r.nodes.builtin.CastBuilder.Predef;
 import com.oracle.truffle.r.nodes.builtin.RBuiltinNode;
@@ -99,6 +103,46 @@ public class FastRInterop {
         }
     }
 
+    @RBuiltin(name = ".fastr.interop.evalFile", visibility = OFF, kind = PRIMITIVE, parameterNames = {"path", "mimeType"}, behavior = COMPLEX)
+    public abstract static class EvalFile extends RBuiltinNode {
+
+        @Override
+        protected void createCasts(CastBuilder casts) {
+            casts.arg("path").mustBe(stringValue()).asStringVector().mustBe(singleElement()).findFirst();
+            casts.arg("mimeType").allowMissing().mustBe(stringValue()).asStringVector().mustBe(singleElement()).findFirst();
+        }
+
+        protected CallTarget parse(String path, String mimeType) {
+            CompilerAsserts.neverPartOfCompilation();
+
+            File file = new File(path);
+            try {
+                Builder<IOException, RuntimeException, RuntimeException> sourceBuilder = Source.newBuilder(file).name(file.getName()).internal();
+                if (mimeType != null) {
+                    sourceBuilder.mimeType(mimeType);
+                }
+                Source sourceObject = sourceBuilder.build();
+                return RContext.getInstance().getEnv().parse(sourceObject);
+            } catch (IOException e) {
+                throw RError.error(this, Message.GENERIC, "Error reading file: " + e.getMessage());
+            } catch (Throwable t) {
+                throw RError.error(this, Message.GENERIC, "Error while parsing: " + t.getMessage());
+            }
+        }
+
+        @Specialization
+        @TruffleBoundary
+        protected Object eval(String path, @SuppressWarnings("unused") RMissing missing) {
+            return parse(path, null).call();
+        }
+
+        @Specialization
+        @TruffleBoundary
+        protected Object eval(String path, String mimeType) {
+            return parse(path, mimeType).call();
+        }
+    }
+
     @RBuiltin(name = ".fastr.interop.export", visibility = OFF, kind = PRIMITIVE, parameterNames = {"name", "value"}, behavior = COMPLEX)
     public abstract static class Export extends RBuiltinNode {
 
diff --git a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/fastr/FastRSyntaxTree.java b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/fastr/FastRSyntaxTree.java
index caed0874e9fe810fa18e624cabbba2f25e540198..0a2a9930f4d4f4adc756ec74feb8e880f36bb076 100644
--- a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/fastr/FastRSyntaxTree.java
+++ b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/fastr/FastRSyntaxTree.java
@@ -62,7 +62,7 @@ import com.oracle.truffle.r.runtime.nodes.RSyntaxVisitor;
  * Only nodes that return {@code true} to {@link RSyntaxNode#isSyntax()} are processed. N.B. This
  * will reach nodes that implement {@link RSyntaxNode} but are used in {@link RSyntaxNode#INTERNAL}
  * mode</li>
- * <li><b<syntaxelement</b>: Use the {@link RSyntaxVisitor} to visit the "logical" syntax tree.</li>
+ * <li><b>syntaxelement</b>: Use the {@link RSyntaxVisitor} to visit the "logical" syntax tree.</li>
  * </ol>
  *
  */
@@ -71,7 +71,7 @@ public abstract class FastRSyntaxTree extends RBuiltinNode {
 
     @Override
     public Object[] getDefaultParameterValues() {
-        return new Object[]{RMissing.instance, "rsyntaxnode", RRuntime.LOGICAL_FALSE, RRuntime.LOGICAL_FALSE};
+        return new Object[]{RMissing.instance, "syntaxelement", RRuntime.LOGICAL_FALSE, RRuntime.LOGICAL_FALSE};
     }
 
     @Override
@@ -110,12 +110,18 @@ public abstract class FastRSyntaxTree extends RBuiltinNode {
                     @Override
                     protected Void visit(RSyntaxCall element) {
                         printIndent(depth);
-                        writeString(element.getClass().getSimpleName(), false);
+                        RSyntaxElement lhs = element.getSyntaxLHS();
+                        if (lhs instanceof RSyntaxLookup) {
+                            writeString(element.getClass().getSimpleName() + " " + ((RSyntaxLookup) lhs).getIdentifier(), false);
+                        } else {
+                            writeString(element.getClass().getSimpleName(), false);
+                        }
                         processSourceSection(element.getSourceSection(), printSource);
                         printnl();
-                        RSyntaxElement lhs = element.getSyntaxLHS();
                         RSyntaxElement[] arguments = element.getSyntaxArguments();
-                        accept(lhs);
+                        if (!(lhs instanceof RSyntaxLookup)) {
+                            accept(lhs);
+                        }
                         for (RSyntaxElement arg : arguments) {
                             depth++;
                             accept(arg);
diff --git a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/utils/R/packages_overrides.R b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/utils/R/packages_overrides.R
deleted file mode 100644
index 0dc6f9fe27335e7b7bd9a53279e914047ccbc833..0000000000000000000000000000000000000000
--- a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/utils/R/packages_overrides.R
+++ /dev/null
@@ -1,56 +0,0 @@
-#  File src/library/utils/R/packages.R
-#  Part of the R package, http://www.R-project.org
-#
-#  Copyright (C) 1995-2014 The R Core Team
-#
-#  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.
-#
-#  A copy of the GNU General Public License is available at
-#  http://www.r-project.org/Licenses/
-
-# An override that works around the problems with numeric version generic ops
-# We have to eval this re-definition in the utils namespace environmment as it is a private function
-# stored in a local map
-
-eval(expression(
-available_packages_filters_db$R_version <-
-		function(db)
-{
-	## Ignore packages which don't fit our version of R.
-	depends <- db[, "Depends"]
-	depends[is.na(depends)] <- ""
-	## Collect the (versioned) R depends entries.
-	x <- lapply(strsplit(sub("^[[:space:]]*", "", depends),
-					"[[:space:]]*,[[:space:]]*"),
-			function(s) s[grepl("^R[[:space:]]*\\(", s)])
-	lens <- sapply(x, length)
-	pos <- which(lens > 0L)
-	if(!length(pos)) return(db)
-	lens <- lens[pos]
-	## Unlist.
-	x <- unlist(x)
-	pat <- "^R[[:space:]]*\\(([[<>=!]+)[[:space:]]+(.*)\\)[[:space:]]*"
-	## Extract ops.
-	ops <- sub(pat, "\\1", x)
-	## Split target versions accordings to ops.
-	v_t <- split(sub(pat, "\\2", x), ops)
-	## Current R version.
-#	v_c <- getRversion()
-	v_c <- as.character(getRversion())
-	## Compare current to target grouped by op.
-	res <- logical(length(x))
-	for(op in names(v_t))
-		res[ops == op] <- do.call(op, list(v_c, v_t[[op]]))
-	## And assemble test results according to the rows of db.
-	ind <- rep.int(TRUE, NROW(db))
-	ind[pos] <- sapply(split(res, rep.int(seq_along(lens), lens)), all)
-	db[ind, , drop = FALSE]
-}), asNamespace("utils"))
diff --git a/com.oracle.truffle.r.nodes.test/src/com/oracle/truffle/r/nodes/test/SpecialCallTest.java b/com.oracle.truffle.r.nodes.test/src/com/oracle/truffle/r/nodes/test/SpecialCallTest.java
index b72e022b321a7d8fa76f41a506f474f6bd84ab90..24af4e1560c7e5e6bea0d1cf987abc3a1b1ad702 100644
--- a/com.oracle.truffle.r.nodes.test/src/com/oracle/truffle/r/nodes/test/SpecialCallTest.java
+++ b/com.oracle.truffle.r.nodes.test/src/com/oracle/truffle/r/nodes/test/SpecialCallTest.java
@@ -28,11 +28,6 @@ import org.junit.Test;
 import com.oracle.truffle.api.RootCallTarget;
 import com.oracle.truffle.api.source.Source;
 import com.oracle.truffle.r.engine.TruffleRLanguage;
-import com.oracle.truffle.r.nodes.access.WriteVariableSyntaxNode;
-import com.oracle.truffle.r.nodes.control.BlockNode;
-import com.oracle.truffle.r.nodes.control.ReplacementDispatchNode;
-import com.oracle.truffle.r.nodes.function.RCallNode;
-import com.oracle.truffle.r.nodes.function.RCallSpecialNode;
 import com.oracle.truffle.r.runtime.ArgumentsSignature;
 import com.oracle.truffle.r.runtime.FastROptions;
 import com.oracle.truffle.r.runtime.RError;
@@ -59,12 +54,23 @@ public class SpecialCallTest extends TestBase {
 
         @Override
         protected Void visit(RSyntaxCall element) {
-            if (element instanceof RCallSpecialNode) {
-                special++;
-            } else if (element instanceof RCallNode) {
-                normal++;
-            } else {
-                assert element instanceof ReplacementDispatchNode || element instanceof WriteVariableSyntaxNode || element instanceof BlockNode : "unexpected node while testing";
+            switch (element.getClass().getSimpleName()) {
+                case "SpecialReplacementNode":
+                case "SpecialVoidReplacementNode":
+                case "RCallSpecialNode":
+                    special++;
+                    break;
+                case "RCallNodeGen":
+                case "GenericReplacementNode":
+                    normal++;
+                    break;
+                case "ReplacementDispatchNode":
+                case "WriteVariableSyntaxNode":
+                case "BlockNode":
+                    // ignored
+                    break;
+                default:
+                    throw new AssertionError("unexpected class: " + element.getClass().getSimpleName());
             }
             accept(element.getSyntaxLHS());
             for (RSyntaxElement arg : element.getSyntaxArguments()) {
@@ -158,81 +164,143 @@ public class SpecialCallTest extends TestBase {
         assertCallCounts("1 + 1", 1, 0, 1, 0);
         assertCallCounts("1 + 1 * 2 + 4", 3, 0, 3, 0);
 
-        assertCallCounts("{ a <- 1; b <- 2; a + b }", 1, 0, 1, 0);
-        assertCallCounts("{ a <- 1; b <- 2; c <- 3; a + b * 2 * c}", 3, 0, 3, 0);
+        assertCallCounts("a <- 1; b <- 2", "a + b", 1, 0, 1, 0);
+        assertCallCounts("a <- 1; b <- 2; c <- 3", "a + b * 2 * c", 3, 0, 3, 0);
 
-        assertCallCounts("{ a <- data.frame(a=1); b <- 2; c <- 3; a + b * 2 * c}", 3, 1, 2, 2);
-        assertCallCounts("{ a <- 1; b <- data.frame(a=1); c <- 3; a + b * 2 * c}", 3, 1, 0, 4);
+        assertCallCounts("a <- data.frame(a=1); b <- 2; c <- 3", "a + b * 2 * c", 3, 0, 2, 1);
+        assertCallCounts("a <- 1; b <- data.frame(a=1); c <- 3", "a + b * 2 * c", 3, 0, 0, 3);
 
         assertCallCounts("1 %*% 1", 0, 1, 0, 1);
     }
 
     @Test
     public void testSubset() {
-        assertCallCounts("{ a <- 1:10; a[1] }", 1, 1, 1, 1);
-        assertCallCounts("{ a <- c(1,2,3,4); a[2] }", 1, 1, 1, 1);
-        assertCallCounts("{ a <- c(1,2,3,4); a[4] }", 1, 1, 1, 1);
-        assertCallCounts("{ a <- list(c(1,2,3,4),2,3); a[1] }", 1, 2, 1, 2);
-
-        assertCallCounts("{ a <- c(1,2,3,4); a[0.1] }", 1, 1, 0, 2);
-        assertCallCounts("{ a <- c(1,2,3,4); a[5] }", 1, 1, 0, 2);
-        assertCallCounts("{ a <- c(1,2,3,4); a[0] }", 1, 1, 0, 2);
-        assertCallCounts("{ a <- c(1,2,3,4); a[-1] }", 0, 3, 0, 3); // "-1" is a unary expression
-        assertCallCounts("{ a <- c(1,2,3,4); b <- -1; a[b] }", 1, 2, 0, 3);
-        assertCallCounts("{ a <- c(1,2,3,4); a[NA_integer_] }", 1, 1, 0, 2);
+        assertCallCounts("a <- 1:10", "a[1]", 1, 0, 1, 0);
+        assertCallCounts("a <- c(1,2,3,4)", "a[2]", 1, 0, 1, 0);
+        assertCallCounts("a <- c(1,2,3,4)", "a[4]", 1, 0, 1, 0);
+        assertCallCounts("a <- list(c(1,2,3,4),2,3)", "a[1]", 1, 0, 1, 0);
+        assertCallCounts("a <- c(1,2,3,4)", "a[0.1]", 1, 0, 1, 0);
+        assertCallCounts("a <- c(1,2,3,4)", "a[5]", 1, 0, 1, 0);
+        assertCallCounts("a <- c(1,2,3,4)", "a[0]", 1, 0, 1, 0);
+        assertCallCounts("a <- c(1,2,3,4); b <- -1", "a[b]", 1, 0, 1, 0);
+        assertCallCounts("a <- c(1,2,3,4)", "a[NA_integer_]", 1, 0, 1, 0);
+
+        assertCallCounts("a <- c(1,2,3,4)", "a[-1]", 0, 2, 0, 2); // "-1" is a unary expression
+        assertCallCounts("a <- c(1,2,3,4)", "a[drop=T, 1]", 0, 1, 0, 1);
+        assertCallCounts("a <- c(1,2,3,4)", "a[drop=F, 1]", 0, 1, 0, 1);
+        assertCallCounts("a <- c(1,2,3,4)", "a[1, drop=F]", 0, 1, 0, 1);
     }
 
     @Test
     public void testSubscript() {
-        assertCallCounts("{ a <- 1:10; a[[1]] }", 1, 1, 1, 1);
-        assertCallCounts("{ a <- c(1,2,3,4); a[[2]] }", 1, 1, 1, 1);
-        assertCallCounts("{ a <- c(1,2,3,4); a[[4]] }", 1, 1, 1, 1);
-        assertCallCounts("{ a <- list(c(1,2,3,4),2,3); a[[1]] }", 1, 2, 1, 2);
-        assertCallCounts("{ a <- list(a=c(1,2,3,4),2,3); a[[1]] }", 1, 2, 1, 2);
-        assertCallCounts("{ a <- c(1,2,3,4); a[[0.1]] }", 1, 1, 1, 1);
-
-        assertCallCounts("{ a <- c(1,2,3,4); a[[5]] }", 1, 1, 0, 2);
-        assertCallCounts("{ a <- c(1,2,3,4); a[[0]] }", 1, 1, 0, 2);
-        assertCallCounts("{ a <- c(1,2,3,4); b <- -1; a[[b]] }", 1, 2, 0, 3);
-        assertCallCounts("{ a <- c(1,2,3,4); a[[NA_integer_]] }", 1, 1, 0, 2);
+        assertCallCounts("a <- 1:10", "a[[1]]", 1, 0, 1, 0);
+        assertCallCounts("a <- c(1,2,3,4)", "a[[2]]", 1, 0, 1, 0);
+        assertCallCounts("a <- c(1,2,3,4)", "a[[4]]", 1, 0, 1, 0);
+        assertCallCounts("a <- list(c(1,2,3,4),2,3)", "a[[1]]", 1, 0, 1, 0);
+        assertCallCounts("a <- list(a=c(1,2,3,4),2,3)", "a[[1]]", 1, 0, 1, 0);
+        assertCallCounts("a <- c(1,2,3,4)", "a[[0.1]]", 1, 0, 1, 0);
+        assertCallCounts("a <- c(1,2,3,4)", "a[[5]]", 1, 0, 1, 0);
+        assertCallCounts("a <- c(1,2,3,4)", "a[[0]]", 1, 0, 1, 0);
+        assertCallCounts("a <- c(1,2,3,4); b <- -1", "a[[b]]", 1, 0, 1, 0);
+        assertCallCounts("a <- c(1,2,3,4)", "a[[NA_integer_]]", 1, 0, 1, 0);
+
+        assertCallCounts("a <- c(1,2,3,4)", "a[[drop=T, 1]]", 0, 1, 0, 1);
+        assertCallCounts("a <- c(1,2,3,4)", "a[[drop=F, 1]]", 0, 1, 0, 1);
+        assertCallCounts("a <- c(1,2,3,4)", "a[[1, drop=F]]", 0, 1, 0, 1);
     }
 
-    private static void assertCallCounts(String str, int initialSpecialCount, int initialNormalCount, int finalSpecialCount, int finalNormalCount) {
+    @Test
+    public void testUpdateSubset() {
+        assertCallCounts("a <- 1:10", "a[1] <- 1", 1, 0, 1, 1); // sequence
+        assertCallCounts("a <- c(1,2,3,4)", "a[2] <- 1", 1, 0, 2, 0);
+        assertCallCounts("a <- c(1,2,3,4)", "a[4] <- 1", 1, 0, 2, 0);
+        assertCallCounts("a <- list(c(1,2,3,4),2,3)", "a[1] <- 1", 1, 0, 2, 0);
+        assertCallCounts("a <- c(1,2,3,4)", "a[0.1] <- 1", 1, 0, 1, 1);
+        assertCallCounts("a <- c(1,2,3,4)", "a[5] <- 1", 1, 0, 1, 1);
+        assertCallCounts("a <- c(1,2,3,4)", "a[0] <- 1", 1, 0, 1, 1);
+        assertCallCounts("a <- c(1,2,3,4); b <- -1", "a[b] <- 1", 1, 0, 1, 1);
+        assertCallCounts("a <- c(1,2,3,4)", "a[NA_integer_] <- 1", 1, 0, 1, 1);
+
+        assertCallCounts("a <- c(1,2,3,4)", "a[-1] <- 1", 0, 2, 0, 3); // "-1" is a unary expression
+        assertCallCounts("a <- c(1,2,3,4)", "a[drop=T, 1] <- 1", 0, 1, 0, 2);
+        assertCallCounts("a <- c(1,2,3,4)", "a[drop=F, 1] <- 1", 0, 1, 0, 2);
+        assertCallCounts("a <- c(1,2,3,4)", "a[1, drop=F] <- 1", 0, 1, 0, 2);
+    }
+
+    @Test
+    public void testUpdateSubscript() {
+        assertCallCounts("a <- 1:10", "a[[1]] <- 1", 1, 0, 1, 1); // sequence
+        assertCallCounts("a <- c(1,2,3,4)", "a[[2]] <- 1", 1, 0, 2, 0);
+        assertCallCounts("a <- c(1,2,3,4)", "a[[4]] <- 1", 1, 0, 2, 0);
+        assertCallCounts("a <- list(c(1,2,3,4),2,3)", "a[[1]] <- 1", 1, 0, 2, 0);
+        assertCallCounts("a <- list(a=c(1,2,3,4),2,3)", "a[[1]] <- 1", 1, 0, 2, 0);
+        assertCallCounts("a <- c(1,2,3,4)", "a[[0.1]] <- 1", 1, 0, 1, 1);
+        assertCallCounts("a <- c(1,2,3,4)", "a[[5]] <- 1", 1, 0, 1, 1);
+        assertCallCounts("a <- c(1,2,3,4)", "a[[0]] <- 1", 1, 0, 1, 1);
+        assertCallCounts("a <- c(1,2,3,4); b <- -1", "a[[b]] <- 1", 1, 0, 1, 1);
+        assertCallCounts("a <- c(1,2,3,4)", "a[[NA_integer_]] <- 1", 1, 0, 1, 1);
+
+        assertCallCounts("a <- c(1,2,3,4)", "a[[drop=T, 1]] <- 1", 0, 1, 0, 2);
+        assertCallCounts("a <- c(1,2,3,4)", "a[[drop=F, 1]] <- 1", 0, 1, 0, 2);
+        assertCallCounts("a <- c(1,2,3,4)", "a[[1, drop=F]] <- 1", 0, 1, 0, 2);
+    }
+
+    @Test
+    public void testParens() {
+        assertCallCounts("a <- 1", "(a)", 1, 0, 1, 0);
+        assertCallCounts("a <- 1", "(55)", 1, 0, 1, 0);
+        assertCallCounts("a <- 1", "('asdf')", 1, 0, 1, 0);
+        assertCallCounts("a <- 1; b <- 2", "(a + b)", 2, 0, 2, 0);
+        assertCallCounts("a <- 1; b <- 2; c <- 3", "a + (b + c)", 3, 0, 3, 0);
+        assertCallCounts("a <- 1; b <- 2; c <- 1:5", "a + (b + c)", 3, 0, 0, 3);
+    }
+
+    private static void assertCallCounts(String test, int initialSpecialCount, int initialNormalCount, int finalSpecialCount, int finalNormalCount) {
+        assertCallCounts("{}", test, initialSpecialCount, initialNormalCount, finalSpecialCount, finalNormalCount);
+    }
+
+    private static void assertCallCounts(String setup, String test, int initialSpecialCount, int initialNormalCount, int finalSpecialCount, int finalNormalCount) {
         if (!FastROptions.UseSpecials.getBooleanValue()) {
             return;
         }
-        Source source = Source.newBuilder(str).mimeType(TruffleRLanguage.MIME).name("test").build();
+        Source setupSource = Source.newBuilder("{" + setup + "}").mimeType(TruffleRLanguage.MIME).name("test").build();
+        Source testSource = Source.newBuilder(test).mimeType(TruffleRLanguage.MIME).name("test").build();
 
-        RExpression expression = testVMContext.getThisEngine().parse(source);
-        assert expression.getLength() == 1;
-        RootCallTarget callTarget = testVMContext.getThisEngine().makePromiseCallTarget(((RLanguage) expression.getDataAt(0)).getRep().asRSyntaxNode().asRNode(), "test");
+        RExpression setupExpression = testVMContext.getThisEngine().parse(setupSource);
+        RExpression testExpression = testVMContext.getThisEngine().parse(testSource);
+        assert setupExpression.getLength() == 1;
+        assert testExpression.getLength() == 1;
+        RootCallTarget setupCallTarget = testVMContext.getThisEngine().makePromiseCallTarget(((RLanguage) setupExpression.getDataAt(0)).getRep().asRSyntaxNode().asRNode(), "test");
+        RootCallTarget testCallTarget = testVMContext.getThisEngine().makePromiseCallTarget(((RLanguage) testExpression.getDataAt(0)).getRep().asRSyntaxNode().asRNode(), "test");
 
         try {
-            CountCallsVisitor count1 = new CountCallsVisitor(callTarget);
-            Assert.assertEquals("initial special call count '" + str + "': ", initialSpecialCount, count1.special);
-            Assert.assertEquals("initial normal call count '" + str + "': ", initialNormalCount, count1.normal);
+            CountCallsVisitor count1 = new CountCallsVisitor(testCallTarget);
+            Assert.assertEquals("initial special call count '" + setup + "; " + test + "': ", initialSpecialCount, count1.special);
+            Assert.assertEquals("initial normal call count '" + setup + "; " + test + "': ", initialNormalCount, count1.normal);
 
             try {
-                callTarget.call(REnvironment.globalEnv().getFrame());
+                setupCallTarget.call(REnvironment.globalEnv().getFrame());
+                testCallTarget.call(REnvironment.globalEnv().getFrame());
             } catch (RError e) {
                 // ignore
             }
 
-            CountCallsVisitor count2 = new CountCallsVisitor(callTarget);
-            Assert.assertEquals("special call count after first call '" + str + "': ", finalSpecialCount, count2.special);
-            Assert.assertEquals("normal call count after first call '" + str + "': ", finalNormalCount, count2.normal);
+            CountCallsVisitor count2 = new CountCallsVisitor(testCallTarget);
+            Assert.assertEquals("special call count after first call '" + setup + "; " + test + "': ", finalSpecialCount, count2.special);
+            Assert.assertEquals("normal call count after first call '" + setup + "; " + test + "': ", finalNormalCount, count2.normal);
 
             try {
-                callTarget.call(REnvironment.globalEnv().getFrame());
+                setupCallTarget.call(REnvironment.globalEnv().getFrame());
+                testCallTarget.call(REnvironment.globalEnv().getFrame());
             } catch (RError e) {
                 // ignore
             }
 
-            CountCallsVisitor count3 = new CountCallsVisitor(callTarget);
-            Assert.assertEquals("special call count after second call '" + str + "': ", finalSpecialCount, count3.special);
-            Assert.assertEquals("normal call count after second call '" + str + "': ", finalNormalCount, count3.normal);
+            CountCallsVisitor count3 = new CountCallsVisitor(testCallTarget);
+            Assert.assertEquals("special call count after second call '" + setup + "; " + test + "': ", finalSpecialCount, count3.special);
+            Assert.assertEquals("normal call count after second call '" + setup + "; " + test + "': ", finalNormalCount, count3.normal);
         } catch (AssertionError e) {
-            new PrintCallsVisitor().print(callTarget);
+            new PrintCallsVisitor().print(testCallTarget);
             throw e;
         }
     }
diff --git a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/RASTBuilder.java b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/RASTBuilder.java
index 90e78439df32c303ec92378b0b5389076df6968f..7b8013d3efc086cdc6b4479260e54af138e2684c 100644
--- a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/RASTBuilder.java
+++ b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/RASTBuilder.java
@@ -38,7 +38,6 @@ import com.oracle.truffle.r.nodes.control.BreakNode;
 import com.oracle.truffle.r.nodes.control.ForNode;
 import com.oracle.truffle.r.nodes.control.IfNode;
 import com.oracle.truffle.r.nodes.control.NextNode;
-import com.oracle.truffle.r.nodes.control.ParNode;
 import com.oracle.truffle.r.nodes.control.RepeatNode;
 import com.oracle.truffle.r.nodes.control.ReplacementDispatchNode;
 import com.oracle.truffle.r.nodes.control.WhileNode;
@@ -92,8 +91,6 @@ public final class RASTBuilder implements RCodeBuilder<RSyntaxNode> {
                 switch (symbol) {
                     case "repeat":
                         return new RepeatNode(source, lhsLookup, args.get(0).value);
-                    case "(":
-                        return new ParNode(source, lhsLookup, args.get(0).value);
                 }
             } else if (args.size() == 2) {
                 switch (symbol) {
@@ -258,6 +255,11 @@ public final class RASTBuilder implements RCodeBuilder<RSyntaxNode> {
         FrameDescriptor descriptor = new FrameDescriptor();
         FrameSlotChangeMonitor.initializeFunctionFrameDescriptor(name != null && !name.isEmpty() ? name : "<function>", descriptor);
         FunctionDefinitionNode rootNode = FunctionDefinitionNode.create(source, descriptor, argSourceSections, saveArguments, body, formals, name, argPostProcess);
+
+        if (FastROptions.ForceSources.getBooleanValue()) {
+            // forces source sections to be generated
+            rootNode.getSourceSection();
+        }
         return Truffle.getRuntime().createCallTarget(rootNode);
     }
 
diff --git a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/RRootNode.java b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/RRootNode.java
index eb785b3c7cc1cda98117c71df3e407934d3390c2..929e53938623402ab75e0db4ae3dfa7b0ab7a697 100644
--- a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/RRootNode.java
+++ b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/RRootNode.java
@@ -27,7 +27,6 @@ import com.oracle.truffle.api.frame.FrameDescriptor;
 import com.oracle.truffle.api.frame.VirtualFrame;
 import com.oracle.truffle.api.nodes.RootNode;
 import com.oracle.truffle.api.profiles.ConditionProfile;
-import com.oracle.truffle.api.source.SourceSection;
 import com.oracle.truffle.r.nodes.builtin.RBuiltinFactory;
 import com.oracle.truffle.r.nodes.builtin.RBuiltinNode;
 import com.oracle.truffle.r.nodes.function.FormalArguments;
@@ -54,20 +53,12 @@ public abstract class RRootNode extends RootNode implements HasSignature {
 
     private FastPathFactory fastPath;
 
-    protected RRootNode(SourceSection src, FormalArguments formalArguments, FrameDescriptor frameDescriptor, FastPathFactory fastPath) {
-        super(RContext.getRForeignAccessFactory().getTruffleLanguage(), checkSourceSection(src), frameDescriptor);
+    protected RRootNode(FormalArguments formalArguments, FrameDescriptor frameDescriptor, FastPathFactory fastPath) {
+        super(RContext.getRForeignAccessFactory().getTruffleLanguage(), RSyntaxNode.SOURCE_UNAVAILABLE, frameDescriptor);
         this.formalArguments = formalArguments;
         this.fastPath = fastPath;
     }
 
-    private static SourceSection checkSourceSection(SourceSection src) {
-        if (src == null) {
-            return RSyntaxNode.SOURCE_UNAVAILABLE;
-        } else {
-            return src;
-        }
-    }
-
     @Override
     public abstract RootCallTarget duplicateWithNewFrameDescriptor();
 
@@ -114,4 +105,9 @@ public abstract class RRootNode extends RootNode implements HasSignature {
     public boolean isCloningAllowed() {
         return true;
     }
+
+    @Override
+    public final String toString() {
+        return getName();
+    }
 }
diff --git a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/RSyntaxNodeVisitor.java b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/RSyntaxNodeVisitor.java
index 8c8468a0f53e9d1ece3e311c23433e84e83dd294..ba3fb48f7dd754a701f9872f68ba27b48103972d 100644
--- a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/RSyntaxNodeVisitor.java
+++ b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/RSyntaxNodeVisitor.java
@@ -26,10 +26,6 @@ public interface RSyntaxNodeVisitor<T> extends IRSyntaxNodeVisitor<T> {
 
     public abstract T visit(final ReadVariableNode var);
 
-    public default T visit(final ParNode par) {
-        return par.getSyntaxArguments()[0].accept(this);
-    }
-
     public abstract T visit(final WriteLocalFrameVariableNode var);
 
     public abstract T visit(final FunctionExpressionNode fun);
@@ -74,8 +70,6 @@ public interface RSyntaxNodeVisitor<T> extends IRSyntaxNodeVisitor<T> {
             return visit((BlockNode) node);
         if (node instanceof ReadVariableNode)
             return visit((ReadVariableNode) node);
-        if (node instanceof ParNode)
-            return visit((ParNode) node);
         if (node instanceof WriteLocalFrameVariableNode)
             return visit((WriteLocalFrameVariableNode) node);
         if (node instanceof FunctionExpressionNode)
diff --git a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/access/AccessSlotNode.java b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/access/AccessSlotNode.java
index e5307e12f2b19f3d435dc30d25e7b497556d3231..6b0743a08d06e22bd1666b8304b55b9b07e169a6 100644
--- a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/access/AccessSlotNode.java
+++ b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/access/AccessSlotNode.java
@@ -81,7 +81,7 @@ public abstract class AccessSlotNode extends RNode {
                 // TODO: any way to cache it or use a mechanism similar to overrides?
                 REnvironment methodsNamespace = REnvironment.getRegisteredNamespace("methods");
                 RFunction dataPart = getDataPartFunction(methodsNamespace);
-                return RContext.getEngine().evalFunction(dataPart, methodsNamespace.getFrame(), RCaller.create(Utils.getActualCurrentFrame(), RASTUtils.getOriginalCall(this)), null, object);
+                return RContext.getEngine().evalFunction(dataPart, methodsNamespace.getFrame(), RCaller.create(null, RASTUtils.getOriginalCall(this)), null, object);
             } else if (name == RRuntime.NAMES_ATTR_KEY && object instanceof RAbstractVector) {
                 assert false; // RS4Object can never be a vector?
                 return RNull.instance;
@@ -134,7 +134,7 @@ public abstract class AccessSlotNode extends RNode {
         // TODO: any way to cache it or use a mechanism similar to overrides?
         REnvironment methodsNamespace = REnvironment.getRegisteredNamespace("methods");
         RFunction dataPart = getDataPartFunction(methodsNamespace);
-        return RContext.getEngine().evalFunction(dataPart, methodsNamespace.getFrame(), RCaller.create(Utils.getActualCurrentFrame(), RASTUtils.getOriginalCall(this)), null, object);
+        return RContext.getEngine().evalFunction(dataPart, methodsNamespace.getFrame(), RCaller.create(null, RASTUtils.getOriginalCall(this)), null, object);
     }
 
     // this is really a fallback specialization but @Fallback does not work here (because of the
diff --git a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/access/UpdateSlotNode.java b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/access/UpdateSlotNode.java
index 22972c305937af31631bec8b43d876dadfb1b80f..6cd9f319cb4dfda349a0105b1be5dcce89ed2a09 100644
--- a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/access/UpdateSlotNode.java
+++ b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/access/UpdateSlotNode.java
@@ -62,7 +62,7 @@ public abstract class UpdateSlotNode extends RNode {
         String identifier = "setDataPart";
         Object f = methodsNamespace.findFunction(identifier);
         RFunction dataPart = (RFunction) RContext.getRRuntimeASTAccess().forcePromise(identifier, f);
-        return RContext.getEngine().evalFunction(dataPart, methodsNamespace.getFrame(), RCaller.create(Utils.getActualCurrentFrame(), RASTUtils.getOriginalCall(this)), null, object,
+        return RContext.getEngine().evalFunction(dataPart, methodsNamespace.getFrame(), RCaller.create(null, RASTUtils.getOriginalCall(this)), null, object,
                         prepareValue(value),
                         RRuntime.LOGICAL_TRUE);
     }
diff --git a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/access/variables/ReadVariableNode.java b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/access/variables/ReadVariableNode.java
index da099379b27d2dde035be4f0c2cd48c14c135918..cf0585f4b13e7078466524a68b3ae09b79fbbb28 100644
--- a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/access/variables/ReadVariableNode.java
+++ b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/access/variables/ReadVariableNode.java
@@ -63,7 +63,7 @@ import com.oracle.truffle.r.runtime.data.RMissing;
 import com.oracle.truffle.r.runtime.data.RNull;
 import com.oracle.truffle.r.runtime.data.RPromise;
 import com.oracle.truffle.r.runtime.data.RTypedValue;
-import com.oracle.truffle.r.runtime.data.RTypes;
+import com.oracle.truffle.r.runtime.data.RTypesFlatLayout;
 import com.oracle.truffle.r.runtime.data.model.RAbstractComplexVector;
 import com.oracle.truffle.r.runtime.data.model.RAbstractDoubleVector;
 import com.oracle.truffle.r.runtime.data.model.RAbstractIntVector;
@@ -85,7 +85,7 @@ import com.oracle.truffle.r.runtime.nodes.RSyntaxNode;
  */
 public final class ReadVariableNode extends RSourceSectionNode implements RSyntaxNode, RSyntaxLookup {
 
-    private static final int MAX_INVALIDATION_COUNT = 3;
+    private static final int MAX_INVALIDATION_COUNT = 8;
 
     private enum ReadKind {
         Normal,
@@ -184,20 +184,22 @@ public final class ReadVariableNode extends RSourceSectionNode implements RSynta
 
         Object result;
         if (read == null) {
-            initializeRead(frame, variableFrame);
+            CompilerDirectives.transferToInterpreterAndInvalidate();
+            initializeRead(frame, variableFrame, false);
         }
         try {
             result = read.execute(frame, variableFrame);
         } catch (InvalidAssumptionException | LayoutChangedException | FrameSlotTypeException e) {
+            CompilerDirectives.transferToInterpreterAndInvalidate();
             int iterations = 0;
             while (true) {
                 iterations++;
-                initializeRead(frame, variableFrame);
+                initializeRead(frame, variableFrame, true);
                 try {
                     result = read.execute(frame, variableFrame);
                 } catch (InvalidAssumptionException | LayoutChangedException | FrameSlotTypeException e2) {
                     if (iterations > 10) {
-                        throw new RInternalError("too many iterations during RVN initialization: " + identifier);
+                        throw new RInternalError("too many iterations during RVN initialization: " + identifier + " " + e2 + " " + read + " " + getRootNode());
                     }
                     continue;
                 }
@@ -217,10 +219,13 @@ public final class ReadVariableNode extends RSourceSectionNode implements RSynta
         return result;
     }
 
-    private void initializeRead(VirtualFrame frame, Frame variableFrame) {
-        CompilerDirectives.transferToInterpreterAndInvalidate();
-        read = initialize(frame, variableFrame);
-        needsCopying = kind == ReadKind.Copying && !(read instanceof Match || read instanceof DescriptorStableMatch);
+    private synchronized void initializeRead(VirtualFrame frame, Frame variableFrame, boolean invalidate) {
+        CompilerAsserts.neverPartOfCompilation();
+        // do nothing if another thread initialized in the meantime
+        if (invalidate || read == null) {
+            read = initialize(frame, variableFrame);
+            needsCopying = kind == ReadKind.Copying && !(read instanceof Match || read instanceof DescriptorStableMatch);
+        }
     }
 
     private static final class LayoutChangedException extends SlowPathException {
@@ -478,27 +483,52 @@ public final class ReadVariableNode extends RSourceSectionNode implements RSynta
     private final class LookupLevel extends DescriptorLevel {
 
         private final LookupResult lookup;
-        private final ValueProfile frameProfile = ValueProfile.createClassProfile();
         private final ConditionProfile nullValueProfile = kind == ReadKind.Silent ? null : ConditionProfile.createBinaryProfile();
 
         private LookupLevel(LookupResult lookup) {
             this.lookup = lookup;
+            assert !(lookup instanceof FrameAndSlotLookupResult);
         }
 
         @Override
         public Object execute(VirtualFrame frame) throws InvalidAssumptionException, LayoutChangedException, FrameSlotTypeException {
-            Object value;
-            if (lookup instanceof FrameAndSlotLookupResult) {
-                FrameAndSlotLookupResult frameAndSlotLookupResult = (FrameAndSlotLookupResult) lookup;
-                value = profiledGetValue(seenValueKinds, frameProfile.profile(frameAndSlotLookupResult.getFrame()), frameAndSlotLookupResult.getSlot());
-            } else {
-                value = lookup.getValue();
-            }
+            Object value = lookup.getValue();
             if (kind != ReadKind.Silent && nullValueProfile.profile(value == null)) {
                 throw RError.error(RError.SHOW_CALLER, mode == RType.Function ? RError.Message.UNKNOWN_FUNCTION : RError.Message.UNKNOWN_OBJECT, identifier);
             }
             return value;
         }
+
+        @Override
+        public String toString() {
+            return "<LU>";
+        }
+    }
+
+    private final class FrameAndSlotLookupLevel extends DescriptorLevel {
+
+        private final FrameAndSlotLookupResult lookup;
+        private final ValueProfile frameProfile = ValueProfile.createClassProfile();
+        private final ConditionProfile isNullProfile = ConditionProfile.createBinaryProfile();
+
+        private FrameAndSlotLookupLevel(FrameAndSlotLookupResult lookup) {
+            this.lookup = lookup;
+        }
+
+        @Override
+        public Object execute(VirtualFrame frame) throws InvalidAssumptionException, LayoutChangedException, FrameSlotTypeException {
+            Object value = profiledGetValue(seenValueKinds, frameProfile.profile(lookup.getFrame()), lookup.getSlot());
+            if (!checkType(frame, value, isNullProfile)) {
+                CompilerDirectives.transferToInterpreterAndInvalidate();
+                throw new LayoutChangedException();
+            }
+            return value;
+        }
+
+        @Override
+        public String toString() {
+            return "<FSLU>";
+        }
     }
 
     private FrameLevel initialize(VirtualFrame frame, Frame variableFrame) {
@@ -538,8 +568,14 @@ public final class ReadVariableNode extends RSourceSectionNode implements RSynta
                     evalPromiseSlowPathWithName(identifierAsString, frame, (RPromise) lookup.getValue());
                 }
                 if (lookup != null) {
-                    if (lookup.getValue() == null || checkTypeSlowPath(frame, lookup.getValue())) {
-                        return new LookupLevel(lookup);
+                    if (lookup instanceof FrameAndSlotLookupResult) {
+                        if (checkTypeSlowPath(frame, lookup.getValue())) {
+                            return new FrameAndSlotLookupLevel((FrameAndSlotLookupResult) lookup);
+                        }
+                    } else {
+                        if (lookup.getValue() == null || checkTypeSlowPath(frame, lookup.getValue())) {
+                            return new LookupLevel(lookup);
+                        }
                     }
                 }
             } catch (InvalidAssumptionException e) {
@@ -880,7 +916,7 @@ public final class ReadVariableNode extends RSourceSectionNode implements RSynta
 /*
  * This is RRuntime.checkType in the node form.
  */
-@TypeSystemReference(RTypes.class)
+@TypeSystemReference(RTypesFlatLayout.class)
 abstract class CheckTypeNode extends RBaseNode {
 
     public abstract boolean executeBoolean(Object o);
diff --git a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/access/vector/ExtractListElement.java b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/access/vector/ExtractListElement.java
index 7d5a0921655097e82255396f22c19b04341c69db..485ca001bcc8c4dc4266b01c4640968f12a74d5e 100644
--- a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/access/vector/ExtractListElement.java
+++ b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/access/vector/ExtractListElement.java
@@ -26,19 +26,16 @@ import com.oracle.truffle.api.dsl.Cached;
 import com.oracle.truffle.api.dsl.Specialization;
 import com.oracle.truffle.api.dsl.TypeSystemReference;
 import com.oracle.truffle.api.nodes.Node;
-import com.oracle.truffle.api.profiles.ConditionProfile;
-import com.oracle.truffle.api.profiles.ValueProfile;
 import com.oracle.truffle.r.nodes.EmptyTypeSystemFlatLayout;
-import com.oracle.truffle.r.nodes.access.vector.ExtractListElementNodeGen.UpdateStateOfListElementNodeGen;
+import com.oracle.truffle.r.nodes.function.opt.UpdateShareableChildValueNode;
 import com.oracle.truffle.r.runtime.data.RListBase;
-import com.oracle.truffle.r.runtime.data.RShareable;
 import com.oracle.truffle.r.runtime.data.model.RAbstractContainer;
 import com.oracle.truffle.r.runtime.data.model.RAbstractListVector;
-import com.oracle.truffle.r.runtime.data.model.RAbstractVector;
 
 /**
  * Internal node that extracts data under given index from any RAbstractContainer. In the case of
- * RListBase, it also invokes {@link UpdateStateOfListElement} on the element before returning it.
+ * RListBase, it also invokes {@link UpdateShareableChildValueNode} on the element before returning
+ * it.
  *
  * There are two reasons for why one accesses an element of a list: to peek at it, possibly
  * calculate some values from it, and then forget it. In such case, it is OK to access the element
@@ -46,9 +43,9 @@ import com.oracle.truffle.r.runtime.data.model.RAbstractVector;
  * {@link RAbstractContainer#getDataAtAsObject(int)}. However, if the object is going to be returned
  * to the user either as return value of a built-in, put inside a list, put as an attribute, or its
  * true reference count matters for some other reason, then its reference count must be put into a
- * consistent state, which is done by {@link UpdateStateOfListElement}. This node is a convenient
- * wrapper that performs the extraction as well as invocation of {@link UpdateStateOfListElement}.
- * See also the documentation of {@link RListBase}.
+ * consistent state, which is done by {@link UpdateShareableChildValueNode}. This node is a
+ * convenient wrapper that performs the extraction as well as invocation of
+ * {@link UpdateShareableChildValueNode}. See also the documentation of {@link RListBase}.
  */
 @TypeSystemReference(EmptyTypeSystemFlatLayout.class)
 public abstract class ExtractListElement extends Node {
@@ -60,7 +57,8 @@ public abstract class ExtractListElement extends Node {
     }
 
     @Specialization
-    protected Object doList(RListBase list, int index, @Cached("create()") UpdateStateOfListElement updateStateNode) {
+    protected Object doList(RListBase list, int index,
+                    @Cached("create()") UpdateShareableChildValueNode updateStateNode) {
         Object element = list.getDataAt(index);
         return updateStateNode.updateState(list, element);
     }
@@ -73,61 +71,4 @@ public abstract class ExtractListElement extends Node {
     protected static boolean isNotList(RAbstractContainer x) {
         return !(x instanceof RAbstractListVector);
     }
-
-    @TypeSystemReference(EmptyTypeSystemFlatLayout.class)
-    public abstract static class UpdateStateOfListElement extends Node {
-
-        public abstract void execute(Object owner, Object item);
-
-        /**
-         * Provides more convenient interface for the {@link #execute(Object, Object)} method.
-         */
-        public final <T> T updateState(RAbstractContainer owner, T item) {
-            execute(owner, item);
-            return item;
-        }
-
-        public static UpdateStateOfListElement create() {
-            return UpdateStateOfListElementNodeGen.create();
-        }
-
-        @Specialization
-        protected void doShareableValues(RListBase owner, RShareable value,
-                        @Cached("createClassProfile()") ValueProfile valueProfile,
-                        @Cached("createBinaryProfile()") ConditionProfile sharedValue,
-                        @Cached("createBinaryProfile()") ConditionProfile temporaryOwner) {
-            RShareable profiledValue = valueProfile.profile(value);
-            if (sharedValue.profile(profiledValue.isShared())) {
-                // it is already shared, not need to do anything
-                return;
-            }
-
-            if (temporaryOwner.profile(owner.isTemporary())) {
-                // This can happen, for example, when we immediately extract out of a temporary
-                // list that was returned by a built-in, like: strsplit(...)[[1L]]. We do not need
-                // to transition the element, it may stay temporary.
-                return;
-            }
-
-            if (profiledValue.isTemporary()) {
-                // make it at least non-shared (parent list must be also at least non-shared)
-                profiledValue.incRefCount();
-            }
-            if (owner.isShared()) {
-                // owner is shared, make the value shared too
-                profiledValue.incRefCount();
-            }
-        }
-
-        @Specialization(guards = "isFallback(owner, value)")
-        protected void doFallback(Object owner, Object value) {
-            assert !(value instanceof RShareable && owner instanceof RAbstractVector && !(owner instanceof RListBase)) : "RShareables can only live inside lists and no other vectors.";
-            // nop: either value is not RShareable, or the owner is "list" like structure with
-            // reference semantics (e.g. REnvironment)
-        }
-
-        protected static boolean isFallback(Object owner, Object value) {
-            return !(value instanceof RShareable) || !(owner instanceof RListBase);
-        }
-    }
 }
diff --git a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/access/vector/PositionCheckSubscriptNode.java b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/access/vector/PositionCheckSubscriptNode.java
index 6aa4578656348d2c47e4ea9f19d82418716a06af..bc43a33bc3f77f8bb4bdec0c85238637caa52577 100644
--- a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/access/vector/PositionCheckSubscriptNode.java
+++ b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/access/vector/PositionCheckSubscriptNode.java
@@ -31,7 +31,6 @@ import com.oracle.truffle.r.runtime.RError;
 import com.oracle.truffle.r.runtime.RError.Message;
 import com.oracle.truffle.r.runtime.RRuntime;
 import com.oracle.truffle.r.runtime.RType;
-import com.oracle.truffle.r.runtime.data.RAttributeProfiles;
 import com.oracle.truffle.r.runtime.data.RDataFactory;
 import com.oracle.truffle.r.runtime.data.RInteger;
 import com.oracle.truffle.r.runtime.data.RMissing;
@@ -48,8 +47,6 @@ abstract class PositionCheckSubscriptNode extends PositionCheckNode {
 
     private final boolean recursive;
 
-    private final RAttributeProfiles attributeProfile = RAttributeProfiles.create();
-
     PositionCheckSubscriptNode(ElementAccessMode mode, RType containerType, Object positionValue, int dimensionIndex, int numDimensions, boolean exact, boolean assignment, boolean recursive) {
         super(mode, containerType, positionValue, dimensionIndex, numDimensions, exact, assignment);
         this.recursive = recursive;
diff --git a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/access/vector/WriteIndexedVectorNode.java b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/access/vector/WriteIndexedVectorNode.java
index b96380cab8e9f6aa985faee814e5818c88a57986..4b3a19907c7d4ba592ee63ebe20d076e1632b40f 100644
--- a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/access/vector/WriteIndexedVectorNode.java
+++ b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/access/vector/WriteIndexedVectorNode.java
@@ -32,8 +32,8 @@ import com.oracle.truffle.api.profiles.BranchProfile;
 import com.oracle.truffle.api.profiles.ConditionProfile;
 import com.oracle.truffle.api.profiles.LoopConditionProfile;
 import com.oracle.truffle.api.profiles.ValueProfile;
-import com.oracle.truffle.r.nodes.access.vector.ExtractListElement.UpdateStateOfListElement;
 import com.oracle.truffle.r.nodes.function.opt.ShareObjectNode;
+import com.oracle.truffle.r.nodes.function.opt.UpdateShareableChildValueNode;
 import com.oracle.truffle.r.nodes.profile.AlwaysOnBranchProfile;
 import com.oracle.truffle.r.nodes.profile.IntValueProfile;
 import com.oracle.truffle.r.nodes.profile.VectorLengthProfile;
@@ -473,14 +473,14 @@ abstract class WriteIndexedVectorNode extends Node {
 
         private final boolean setListElementAsObject;
         private final boolean isReplace;
-        @Child private UpdateStateOfListElement updateStateOfListElement;
+        @Child private UpdateShareableChildValueNode updateStateOfListElement;
         @Child private ShareObjectNode shareObjectNode;
 
         WriteListAction(boolean setListElementAsObject, boolean isReplace) {
             this.setListElementAsObject = setListElementAsObject;
             this.isReplace = isReplace;
             if (!isReplace) {
-                updateStateOfListElement = UpdateStateOfListElement.create();
+                updateStateOfListElement = UpdateShareableChildValueNode.create();
             } else {
                 shareObjectNode = ShareObjectNode.create();
             }
diff --git a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/attributes/ArrayAttributeNode.java b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/attributes/ArrayAttributeNode.java
index 7671b2971d04890eee553ae87d73d8522131d786..cfe144c94ac383973b0dd0babfa49227070b4415 100644
--- a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/attributes/ArrayAttributeNode.java
+++ b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/attributes/ArrayAttributeNode.java
@@ -24,23 +24,33 @@ package com.oracle.truffle.r.nodes.attributes;
 
 import java.util.List;
 
+import com.oracle.truffle.api.CompilerDirectives;
 import com.oracle.truffle.api.dsl.Cached;
 import com.oracle.truffle.api.dsl.Specialization;
 import com.oracle.truffle.api.nodes.ExplodeLoop;
 import com.oracle.truffle.api.object.DynamicObject;
 import com.oracle.truffle.api.object.Property;
 import com.oracle.truffle.api.object.Shape;
+import com.oracle.truffle.api.profiles.BranchProfile;
+import com.oracle.truffle.api.profiles.ConditionProfile;
+import com.oracle.truffle.api.profiles.ValueProfile;
+import com.oracle.truffle.r.runtime.data.RAttributable;
+import com.oracle.truffle.r.runtime.data.RAttributeStorage;
 import com.oracle.truffle.r.runtime.data.RAttributesLayout;
 import com.oracle.truffle.r.runtime.data.RAttributesLayout.AttrsLayout;
 import com.oracle.truffle.r.runtime.data.RAttributesLayout.RAttribute;
 
 public abstract class ArrayAttributeNode extends AttributeIterativeAccessNode {
 
+    private static final RAttribute[] EMPTY = new RAttribute[0];
+
+    @Child private ArrayAttributeNode recursive;
+
     public static ArrayAttributeNode create() {
         return ArrayAttributeNodeGen.create();
     }
 
-    public abstract RAttribute[] execute(DynamicObject attrs);
+    public abstract RAttribute[] execute(Object attrs);
 
     @Specialization(limit = "CACHE_LIMIT", guards = {"attrsLayout != null", "attrsLayout.shape.check(attrs)"})
     @ExplodeLoop
@@ -69,7 +79,29 @@ public abstract class ArrayAttributeNode extends AttributeIterativeAccessNode {
         }
 
         return result;
-
     }
 
+    @Specialization
+    protected RAttribute[] getArrayFallback(RAttributable x,
+                    @Cached("create()") BranchProfile attrNullProfile,
+                    @Cached("createBinaryProfile()") ConditionProfile attrStorageProfile,
+                    @Cached("createClassProfile()") ValueProfile xTypeProfile) {
+        DynamicObject attributes;
+        if (attrStorageProfile.profile(x instanceof RAttributeStorage)) {
+            attributes = ((RAttributeStorage) x).getAttributes();
+        } else {
+            attributes = xTypeProfile.profile(x).getAttributes();
+        }
+
+        if (attributes == null) {
+            attrNullProfile.enter();
+            return EMPTY;
+        }
+        if (recursive == null) {
+            CompilerDirectives.transferToInterpreterAndInvalidate();
+            recursive = insert(create());
+        }
+
+        return recursive.execute(attributes);
+    }
 }
diff --git a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/attributes/AttributeAccessNode.java b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/attributes/AttributeAccessNode.java
index d67f5a81d74a009919ed2ad01e5122267b66bc22..e2a414911323b364302744e8d9cb89adf778de82 100644
--- a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/attributes/AttributeAccessNode.java
+++ b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/attributes/AttributeAccessNode.java
@@ -23,16 +23,19 @@
 package com.oracle.truffle.r.nodes.attributes;
 
 import com.oracle.truffle.api.CompilerAsserts;
+import com.oracle.truffle.api.dsl.TypeSystemReference;
 import com.oracle.truffle.api.object.DynamicObject;
 import com.oracle.truffle.api.object.Location;
 import com.oracle.truffle.api.object.Property;
 import com.oracle.truffle.api.object.Shape;
+import com.oracle.truffle.r.nodes.EmptyTypeSystemFlatLayout;
 import com.oracle.truffle.r.runtime.nodes.RBaseNode;
 
 /**
  * The base class for the nodes that get/set/remove attributes. It encapsulates the common methods
  * used in guards and for caching.
  */
+@TypeSystemReference(EmptyTypeSystemFlatLayout.class)
 public abstract class AttributeAccessNode extends RBaseNode {
 
     protected AttributeAccessNode() {
@@ -65,4 +68,24 @@ public abstract class AttributeAccessNode extends RBaseNode {
         return shape != null && shape.check(attrs);
     }
 
+    protected static Shape defineProperty(Shape oldShape, Object name, Object value) {
+        return oldShape.defineProperty(name, value, 0);
+    }
+
+    /**
+     * There is a subtle difference between {@link Location#canSet} and {@link Location#canStore}.
+     * We need {@link Location#canSet} for the guard of {@code setExistingAttrCached} because there
+     * we call {@link Location#set}. We use the more relaxed {@link Location#canStore} for the guard
+     * of {@code setNewAttrCached} because there we perform a shape transition, i.e., we are not
+     * actually setting the value of the new location - we only transition to this location as part
+     * of the shape change.
+     */
+    protected static boolean canSet(Location location, Object value) {
+        return location.canSet(value);
+    }
+
+    /** See {@link #canSet} for the difference between the two methods. */
+    protected static boolean canStore(Location location, Object value) {
+        return location.canStore(value);
+    }
 }
diff --git a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/attributes/AttributeIterativeAccessNode.java b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/attributes/AttributeIterativeAccessNode.java
index a0eee1c48c83079f7a08ce425e143249a7167d50..525c7491fe44c695ec4b011174e7c4b84e092a0e 100644
--- a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/attributes/AttributeIterativeAccessNode.java
+++ b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/attributes/AttributeIterativeAccessNode.java
@@ -24,11 +24,13 @@ package com.oracle.truffle.r.nodes.attributes;
 
 import com.oracle.truffle.api.CompilerAsserts;
 import com.oracle.truffle.api.CompilerDirectives.TruffleBoundary;
+import com.oracle.truffle.api.dsl.TypeSystemReference;
 import com.oracle.truffle.api.nodes.ExplodeLoop;
 import com.oracle.truffle.api.object.DynamicObject;
 import com.oracle.truffle.api.object.Property;
 import com.oracle.truffle.api.object.Shape;
 import com.oracle.truffle.api.profiles.ConditionProfile;
+import com.oracle.truffle.r.nodes.EmptyTypeSystemFlatLayout;
 import com.oracle.truffle.r.runtime.data.RAttributesLayout;
 import com.oracle.truffle.r.runtime.data.RAttributesLayout.AttrsLayout;
 import com.oracle.truffle.r.runtime.nodes.RBaseNode;
@@ -41,6 +43,7 @@ import com.oracle.truffle.r.runtime.nodes.RBaseNode;
  * properties (i.e. attributes) it is unnecessary to invoke method {@link Shape#getPropertyList()},
  * which would be more expensive.
  */
+@TypeSystemReference(EmptyTypeSystemFlatLayout.class)
 public abstract class AttributeIterativeAccessNode extends RBaseNode {
 
     protected static final int CACHE_LIMIT = RAttributesLayout.LAYOUTS.length;
diff --git a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/attributes/IterableAttributeNode.java b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/attributes/IterableAttributeNode.java
index 99decfc061953e1c6bc18a7cd0b6d8c317a57870..9032aaefedfbd5b61744a27671cf38dc243df9f7 100644
--- a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/attributes/IterableAttributeNode.java
+++ b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/attributes/IterableAttributeNode.java
@@ -22,20 +22,28 @@
  */
 package com.oracle.truffle.r.nodes.attributes;
 
+import com.oracle.truffle.api.CompilerDirectives;
 import com.oracle.truffle.api.CompilerDirectives.TruffleBoundary;
 import com.oracle.truffle.api.dsl.Cached;
 import com.oracle.truffle.api.dsl.Specialization;
 import com.oracle.truffle.api.object.DynamicObject;
+import com.oracle.truffle.api.profiles.BranchProfile;
+import com.oracle.truffle.api.profiles.ConditionProfile;
+import com.oracle.truffle.api.profiles.ValueProfile;
+import com.oracle.truffle.r.runtime.data.RAttributable;
+import com.oracle.truffle.r.runtime.data.RAttributeStorage;
 import com.oracle.truffle.r.runtime.data.RAttributesLayout;
 import com.oracle.truffle.r.runtime.data.RAttributesLayout.AttrsLayout;
 
 public abstract class IterableAttributeNode extends AttributeIterativeAccessNode {
 
+    @Child private IterableAttributeNode recursive;
+
     public static IterableAttributeNode create() {
         return IterableAttributeNodeGen.create();
     }
 
-    public abstract RAttributesLayout.RAttributeIterable execute(DynamicObject attrs);
+    public abstract RAttributesLayout.RAttributeIterable execute(Object attr);
 
     @Specialization(limit = "CACHE_LIMIT", guards = {"attrsLayout != null", "shapeCheck(attrsLayout.shape, attrs)"})
     protected RAttributesLayout.RAttributeIterable getArrayFromConstantLayouts(DynamicObject attrs,
@@ -49,4 +57,27 @@ public abstract class IterableAttributeNode extends AttributeIterativeAccessNode
         return RAttributesLayout.asIterable(attrs);
     }
 
+    @Specialization
+    protected RAttributesLayout.RAttributeIterable getArrayFallback(RAttributable x,
+                    @Cached("create()") BranchProfile attrNullProfile,
+                    @Cached("createBinaryProfile()") ConditionProfile attrStorageProfile,
+                    @Cached("createClassProfile()") ValueProfile xTypeProfile) {
+        DynamicObject attributes;
+        if (attrStorageProfile.profile(x instanceof RAttributeStorage)) {
+            attributes = ((RAttributeStorage) x).getAttributes();
+        } else {
+            attributes = xTypeProfile.profile(x).getAttributes();
+        }
+
+        if (attributes == null) {
+            attrNullProfile.enter();
+            return RAttributesLayout.RAttributeIterable.EMPTY;
+        }
+        if (recursive == null) {
+            CompilerDirectives.transferToInterpreterAndInvalidate();
+            recursive = insert(create());
+        }
+
+        return recursive.execute(attributes);
+    }
 }
diff --git a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/attributes/SetAttributeNode.java b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/attributes/SetAttributeNode.java
index aecd9e3c0fc95b1f2f6cdb3c2bb80e3c5ff862da..812da601b1a5581809264d37ed878d6a60ac49d1 100644
--- a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/attributes/SetAttributeNode.java
+++ b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/attributes/SetAttributeNode.java
@@ -34,6 +34,7 @@ import com.oracle.truffle.api.object.Shape;
 import com.oracle.truffle.api.profiles.BranchProfile;
 import com.oracle.truffle.api.profiles.ConditionProfile;
 import com.oracle.truffle.api.profiles.ValueProfile;
+import com.oracle.truffle.r.nodes.function.opt.ShareObjectNode;
 import com.oracle.truffle.r.runtime.RInternalError;
 import com.oracle.truffle.r.runtime.data.RAttributable;
 import com.oracle.truffle.r.runtime.data.RAttributeStorage;
@@ -77,9 +78,9 @@ public abstract class SetAttributeNode extends AttributeAccessNode {
                     @Cached("lookupShape(attrs)") Shape shape,
                     @Cached("lookupLocation(shape, name, value)") Location location) {
         try {
-            location.set(attrs, value);
+            location.set(attrs, value, shape);
         } catch (IncompatibleLocationException | FinalLocationException ex) {
-            RInternalError.reportError(ex);
+            throw RInternalError.shouldNotReachHere(ex);
         }
     }
 
@@ -104,7 +105,7 @@ public abstract class SetAttributeNode extends AttributeAccessNode {
         try {
             newLocation.set(attrs, value, oldShape, newShape);
         } catch (IncompatibleLocationException ex) {
-            RInternalError.reportError(ex);
+            throw RInternalError.shouldNotReachHere(ex);
         }
     }
 
@@ -148,7 +149,8 @@ public abstract class SetAttributeNode extends AttributeAccessNode {
     protected void setAttrInAttributable(RAttributable x, String name, Object value,
                     @Cached("create()") BranchProfile attrNullProfile,
                     @Cached("createBinaryProfile()") ConditionProfile attrStorageProfile,
-                    @Cached("createClassProfile()") ValueProfile xTypeProfile) {
+                    @Cached("createClassProfile()") ValueProfile xTypeProfile,
+                    @Cached("create()") ShareObjectNode updateRefCountNode) {
         DynamicObject attributes;
         if (attrStorageProfile.profile(x instanceof RAttributeStorage)) {
             attributes = ((RAttributeStorage) x).getAttributes();
@@ -167,6 +169,11 @@ public abstract class SetAttributeNode extends AttributeAccessNode {
         }
 
         recursive.execute(attributes, name, value);
+
+        // TODO: To verify: It might be beneficial to increment the reference counter only if the
+        // old and new values differ. One should verify, though, whether the costs brought about by
+        // reading the old value do not prevail in the end.
+        updateRefCountNode.execute(value);
     }
 
     /**
@@ -182,26 +189,4 @@ public abstract class SetAttributeNode extends AttributeAccessNode {
 
         return location;
     }
-
-    protected static Shape defineProperty(Shape oldShape, Object name, Object value) {
-        return oldShape.defineProperty(name, value, 0);
-    }
-
-    /**
-     * There is a subtle difference between {@link Location#canSet} and {@link Location#canStore}.
-     * We need {@link Location#canSet} for the guard of {@link #setExistingAttrCached} because there
-     * we call {@link Location#set}. We use the more relaxed {@link Location#canStore} for the guard
-     * of {@link #setNewAttrCached} because there we perform a shape transition, i.e., we are not
-     * actually setting the value of the new location - we only transition to this location as part
-     * of the shape change.
-     */
-    protected static boolean canSet(Location location, Object value) {
-        return location.canSet(value);
-    }
-
-    /** See {@link #canSet} for the difference between the two methods. */
-    protected static boolean canStore(Location location, Object value) {
-        return location.canStore(value);
-    }
-
 }
diff --git a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/attributes/SetFixedAttributeNode.java b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/attributes/SetFixedAttributeNode.java
index fd79ede63e6e57041d801f7eecbd7355ca1f50e6..10c91bce2499c7bd5398c7adaa29d225fa3bcd79 100644
--- a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/attributes/SetFixedAttributeNode.java
+++ b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/attributes/SetFixedAttributeNode.java
@@ -35,6 +35,7 @@ import com.oracle.truffle.api.profiles.BranchProfile;
 import com.oracle.truffle.api.profiles.ConditionProfile;
 import com.oracle.truffle.api.profiles.ValueProfile;
 import com.oracle.truffle.r.nodes.attributes.SpecialAttributesFunctions.SetSpecialAttributeNode;
+import com.oracle.truffle.r.nodes.function.opt.ShareObjectNode;
 import com.oracle.truffle.r.runtime.RInternalError;
 import com.oracle.truffle.r.runtime.data.RAttributable;
 import com.oracle.truffle.r.runtime.data.RAttributeStorage;
@@ -85,7 +86,7 @@ public abstract class SetFixedAttributeNode extends FixedAttributeAccessNode {
     public abstract void execute(Object attr, Object value);
 
     @Specialization(limit = "3", //
-                    guards = {"shapeCheck(shape, attrs)", "location != null"}, //
+                    guards = {"shapeCheck(shape, attrs)", "location != null", "canSet(location, value)"}, //
                     assumptions = {"shape.getValidAssumption()"})
     protected void setAttrCached(DynamicObject attrs, Object value,
                     @Cached("lookupShape(attrs)") Shape shape,
@@ -93,12 +94,12 @@ public abstract class SetFixedAttributeNode extends FixedAttributeAccessNode {
         try {
             location.set(attrs, value, shape);
         } catch (IncompatibleLocationException | FinalLocationException ex) {
-            RInternalError.reportError(ex);
+            throw RInternalError.shouldNotReachHere(ex);
         }
     }
 
     @Specialization(limit = "3", //
-                    guards = {"shapeCheck(oldShape, attrs)", "oldLocation == null"}, //
+                    guards = {"shapeCheck(oldShape, attrs)", "oldLocation == null", "canStore(newLocation, value)"}, //
                     assumptions = {"oldShape.getValidAssumption()", "newShape.getValidAssumption()"})
     protected static void setNewAttrCached(DynamicObject attrs, Object value,
                     @Cached("lookupShape(attrs)") Shape oldShape,
@@ -108,7 +109,7 @@ public abstract class SetFixedAttributeNode extends FixedAttributeAccessNode {
         try {
             newLocation.set(attrs, value, oldShape, newShape);
         } catch (IncompatibleLocationException ex) {
-            RInternalError.reportError(ex);
+            throw RInternalError.shouldNotReachHere(ex);
         }
     }
 
@@ -126,7 +127,8 @@ public abstract class SetFixedAttributeNode extends FixedAttributeAccessNode {
     protected void setAttrInAttributable(RAttributable x, Object value,
                     @Cached("create()") BranchProfile attrNullProfile,
                     @Cached("createBinaryProfile()") ConditionProfile attrStorageProfile,
-                    @Cached("createClassProfile()") ValueProfile xTypeProfile) {
+                    @Cached("createClassProfile()") ValueProfile xTypeProfile,
+                    @Cached("create()") ShareObjectNode updateRefCountNode) {
         DynamicObject attributes;
         if (attrStorageProfile.profile(x instanceof RAttributeStorage)) {
             attributes = ((RAttributeStorage) x).getAttributes();
@@ -145,6 +147,8 @@ public abstract class SetFixedAttributeNode extends FixedAttributeAccessNode {
         }
 
         recursive.execute(attributes, value);
+
+        updateRefCountNode.execute(value);
     }
 
 }
diff --git a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/attributes/SpecialAttributesFunctions.java b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/attributes/SpecialAttributesFunctions.java
index e596ca4f5b734b8f433cb47a4b912ab49de67e0a..bc0e2c8a3a6f17199f309e76b7b0f31b9606d8da 100644
--- a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/attributes/SpecialAttributesFunctions.java
+++ b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/attributes/SpecialAttributesFunctions.java
@@ -31,6 +31,7 @@ import com.oracle.truffle.api.profiles.ConditionProfile;
 import com.oracle.truffle.api.profiles.LoopConditionProfile;
 import com.oracle.truffle.api.profiles.ValueProfile;
 import com.oracle.truffle.r.nodes.attributes.SpecialAttributesFunctionsFactory.GetDimAttributeNodeGen;
+import com.oracle.truffle.r.nodes.function.opt.ShareObjectNode;
 import com.oracle.truffle.r.runtime.RError;
 import com.oracle.truffle.r.runtime.RInternalError;
 import com.oracle.truffle.r.runtime.RRuntime;
@@ -318,7 +319,8 @@ public final class SpecialAttributesFunctions {
                         @Cached("create()") SetDimNamesAttributeNode setDimNamesNode,
                         @Cached("create()") BranchProfile attrNullProfile,
                         @Cached("createBinaryProfile()") ConditionProfile attrStorageProfile,
-                        @Cached("createClassProfile()") ValueProfile xTypeProfile) {
+                        @Cached("createClassProfile()") ValueProfile xTypeProfile,
+                        @Cached("create()") ShareObjectNode updateRefCountNode) {
             RVector<?> xProfiled = xTypeProfile.profile(x);
             if (newNames.getLength() > xProfiled.getLength()) {
                 namesTooLongProfile.enter();
@@ -342,7 +344,7 @@ public final class SpecialAttributesFunctions {
                     return;
                 }
 
-                super.setAttrInAttributable(xProfiled, newNames, attrNullProfile, attrStorageProfile, xTypeProfile);
+                super.setAttrInAttributable(xProfiled, newNames, attrNullProfile, attrStorageProfile, xTypeProfile, updateRefCountNode);
             }
         }
 
@@ -454,7 +456,8 @@ public final class SpecialAttributesFunctions {
         protected void setOneDimInVector(RVector<?> x, int dim,
                         @Cached("create()") BranchProfile attrNullProfile,
                         @Cached("createBinaryProfile()") ConditionProfile attrStorageProfile,
-                        @Cached("createClassProfile()") ValueProfile xTypeProfile) {
+                        @Cached("createClassProfile()") ValueProfile xTypeProfile,
+                        @Cached("create()") ShareObjectNode updateRefCountNode) {
             RAbstractContainer xProfiled = contArgClassProfile.profile(x);
 
             int[] dims = new int[]{dim};
@@ -467,17 +470,19 @@ public final class SpecialAttributesFunctions {
                 attrNullProfile.enter();
                 attrs = RAttributesLayout.createDim(dimVec);
                 xProfiled.initAttributes(attrs);
+                updateRefCountNode.execute(dimVec);
                 return;
             }
 
-            super.setAttrInAttributable(x, dimVec, attrNullProfile, attrStorageProfile, xTypeProfile);
+            super.setAttrInAttributable(x, dimVec, attrNullProfile, attrStorageProfile, xTypeProfile, updateRefCountNode);
         }
 
         @Specialization(insertBefore = "setAttrInAttributable")
         protected void setDimsInVector(RVector<?> x, RAbstractIntVector dims,
                         @Cached("create()") BranchProfile attrNullProfile,
                         @Cached("createBinaryProfile()") ConditionProfile attrStorageProfile,
-                        @Cached("createClassProfile()") ValueProfile xTypeProfile) {
+                        @Cached("createClassProfile()") ValueProfile xTypeProfile,
+                        @Cached("create()") ShareObjectNode updateRefCountNode) {
             RAbstractContainer xProfiled = contArgClassProfile.profile(x);
             verifyDimensions(xProfiled.getLength(), dims);
 
@@ -486,10 +491,11 @@ public final class SpecialAttributesFunctions {
                 attrNullProfile.enter();
                 attrs = RAttributesLayout.createDim(dims);
                 xProfiled.initAttributes(attrs);
+                updateRefCountNode.execute(dims);
                 return;
             }
 
-            super.setAttrInAttributable(x, dims, attrNullProfile, attrStorageProfile, xTypeProfile);
+            super.setAttrInAttributable(x, dims, attrNullProfile, attrStorageProfile, xTypeProfile, updateRefCountNode);
         }
 
         @Specialization(insertBefore = "setAttrInAttributable")
@@ -683,7 +689,8 @@ public final class SpecialAttributesFunctions {
                         @Cached("create()") BranchProfile resizeDimsProfile,
                         @Cached("create()") BranchProfile attrNullProfile,
                         @Cached("createBinaryProfile()") ConditionProfile attrStorageProfile,
-                        @Cached("createClassProfile()") ValueProfile xTypeProfile) {
+                        @Cached("createClassProfile()") ValueProfile xTypeProfile,
+                        @Cached("create()") ShareObjectNode updateRefCountNode) {
             int[] dimensions = getDimNode.getDimensions(x);
             if (dimensions == null) {
                 nullDimsProfile.enter();
@@ -727,10 +734,11 @@ public final class SpecialAttributesFunctions {
             if (x.getAttributes() == null) {
                 attrNullProfile.enter();
                 x.initAttributes(RAttributesLayout.createDimNames(resDimNames));
+                updateRefCountNode.execute(resDimNames);
                 return;
             }
 
-            super.setAttrInAttributable(x, resDimNames, attrNullProfile, attrStorageProfile, xTypeProfile);
+            super.setAttrInAttributable(x, resDimNames, attrNullProfile, attrStorageProfile, xTypeProfile, updateRefCountNode);
         }
 
         private static boolean isValidDimLength(RStringVector x, int expectedDim) {
@@ -824,13 +832,15 @@ public final class SpecialAttributesFunctions {
         protected void setRowNamesInVector(RVector<?> x, RAbstractVector newRowNames,
                         @Cached("create()") BranchProfile attrNullProfile,
                         @Cached("createBinaryProfile()") ConditionProfile attrStorageProfile,
-                        @Cached("createClassProfile()") ValueProfile xTypeProfile) {
+                        @Cached("createClassProfile()") ValueProfile xTypeProfile,
+                        @Cached("create()") ShareObjectNode updateRefCountNode) {
             if (x.getAttributes() == null) {
                 attrNullProfile.enter();
                 x.initAttributes(RAttributesLayout.createRowNames(newRowNames));
+                updateRefCountNode.execute(newRowNames);
                 return;
             }
-            setAttrInAttributable(x, newRowNames, attrNullProfile, attrStorageProfile, xTypeProfile);
+            setAttrInAttributable(x, newRowNames, attrNullProfile, attrStorageProfile, xTypeProfile, updateRefCountNode);
         }
 
         @Specialization(insertBefore = "setAttrInAttributable")
@@ -923,8 +933,9 @@ public final class SpecialAttributesFunctions {
                         @Cached("createBinaryProfile()") ConditionProfile nullClassProfile,
                         @Cached("createBinaryProfile()") ConditionProfile notNullClassProfile,
                         @Cached("createBinaryProfile()") ConditionProfile attrStorageProfile,
-                        @Cached("createClassProfile()") ValueProfile xTypeProfile) {
-            handleVector(vector, null, removeClassAttrNode, initAttrProfile, nullAttrProfile, nullClassProfile, notNullClassProfile, attrStorageProfile, xTypeProfile);
+                        @Cached("createClassProfile()") ValueProfile xTypeProfile,
+                        @Cached("create()") ShareObjectNode updateRefCountNode) {
+            handleVector(vector, null, removeClassAttrNode, initAttrProfile, nullAttrProfile, nullClassProfile, notNullClassProfile, attrStorageProfile, xTypeProfile, updateRefCountNode);
         }
 
         @Specialization(insertBefore = "setAttrInAttributable")
@@ -935,7 +946,8 @@ public final class SpecialAttributesFunctions {
                         @Cached("createBinaryProfile()") ConditionProfile nullClassProfile,
                         @Cached("createBinaryProfile()") ConditionProfile notNullClassProfile,
                         @Cached("createBinaryProfile()") ConditionProfile attrStorageProfile,
-                        @Cached("createClassProfile()") ValueProfile xTypeProfile) {
+                        @Cached("createClassProfile()") ValueProfile xTypeProfile,
+                        @Cached("create()") ShareObjectNode updateRefCountNode) {
 
             DynamicObject attrs = vector.getAttributes();
             boolean initializeAttrs = initAttrProfile.profile(attrs == null && classAttr != null && classAttr.getLength() != 0);
@@ -943,6 +955,7 @@ public final class SpecialAttributesFunctions {
                 nullAttrProfile.enter();
                 attrs = RAttributesLayout.createClass(classAttr);
                 vector.initAttributes(attrs);
+                updateRefCountNode.execute(classAttr);
             }
             if (nullClassProfile.profile(attrs != null && (classAttr == null || classAttr.getLength() == 0))) {
                 removeAttributeMapping(vector, attrs, removeClassAttrNode);
@@ -953,7 +966,7 @@ public final class SpecialAttributesFunctions {
                         // TODO: Isn't this redundant when the same operation is done after the
                         // loop?
                         if (!initializeAttrs) {
-                            super.setAttrInAttributable(vector, classAttr, nullAttrProfile, attrStorageProfile, xTypeProfile);
+                            super.setAttrInAttributable(vector, classAttr, nullAttrProfile, attrStorageProfile, xTypeProfile, updateRefCountNode);
                         }
                         // setClassAttrNode.execute(attrs, classAttr);
                         if (vector.getElementClass() != RInteger.class) {
@@ -971,7 +984,7 @@ public final class SpecialAttributesFunctions {
                 }
 
                 if (!initializeAttrs) {
-                    super.setAttrInAttributable(vector, classAttr, nullAttrProfile, attrStorageProfile, xTypeProfile);
+                    super.setAttrInAttributable(vector, classAttr, nullAttrProfile, attrStorageProfile, xTypeProfile, updateRefCountNode);
                 }
             }
         }
diff --git a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/attributes/package-info.java b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/attributes/package-info.java
new file mode 100644
index 0000000000000000000000000000000000000000..b9490530d1b5e41a61fddeef56b05ea61df7702d
--- /dev/null
+++ b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/attributes/package-info.java
@@ -0,0 +1,144 @@
+/*
+ * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/**
+ * <h2>Attributes handling nodes</h2> Generally, this package contains nodes performing basic
+ * operations on attributes, such as setting, getting, removing and iterating. To achieve better
+ * performance, these nodes should be used in preference to the methods on the objects carrying
+ * attributes. In essence, the <code>execute</code> method of each node accepts as its first
+ * argument an object carrying attributes, which may be either an instance of
+ * {@link com.oracle.truffle.api.object.DynamicObject} or
+ * {@link com.oracle.truffle.r.runtime.data.RAttributable} (i.e. lists, vectors etc.).
+ * <p>
+ * <h3>Arbitrary attribute nodes</h3> The nodes in this group operate on the attribute specified as
+ * the second argument of the <code>execute</code> method.
+ * <ul>
+ * <li>{@link com.oracle.truffle.r.nodes.attributes.GetAttributeNode}: retrieves the value of an
+ * arbitrary attribute
+ * <li>{@link com.oracle.truffle.r.nodes.attributes.SetAttributeNode}: sets the value of an
+ * arbitrary attribute. If the first argument is an instance
+ * {@link com.oracle.truffle.r.runtime.data.RAttributable}, the node initializes the object with the
+ * empty attributes.
+ * </ul>
+ *
+ * <h3>Fixed attribute nodes</h3> The nodes in this group operate on the attribute that is specified
+ * during the initialization of a node.
+ * <ul>
+ * <li>{@link com.oracle.truffle.r.nodes.attributes.GetFixedAttributeNode}: retrieves the value of
+ * the predefined attribute
+ * <li>{@link com.oracle.truffle.r.nodes.attributes.HasFixedAttributeNode}: determines the existence
+ * of the predefined attribute
+ * <li>{@link com.oracle.truffle.r.nodes.attributes.SetFixedAttributeNode}: sets the value of the
+ * predefined attribute. If the first argument is an instance
+ * {@link com.oracle.truffle.r.runtime.data.RAttributable}, the node initializes the object with the
+ * empty attributes.
+ * <li>{@link com.oracle.truffle.r.nodes.attributes.RemoveFixedAttributeNode}: removes the
+ * predefined attribute
+ * </ul>
+ * There are additional subclasses of the above-mentioned nodes handling the special attributes,
+ * such as <code>names</code>, <code>dimnames</code> etc.
+ *
+ * <h3>Special attributes handling</h3> The nodes handling the special attributes are derived from
+ * the fixed attribute nodes described in the previous section. The logic in these special attribute
+ * nodes implements side-effects that take place when a given special attribute is retrieved from,
+ * set to or removed from an instance of {@link com.oracle.truffle.r.runtime.data.RAttributable}.
+ * <p>
+ * N.B. The nodes define additional specializations reflecting the fact that those side-effects are
+ * polymorphic (i.e. they may depend on the particular class). These specializations implement in a
+ * more efficient way the logic of their counterparts in attributable objects (such as
+ * {@link com.oracle.truffle.r.runtime.data.model.RAbstractContainer#setDimNames(com.oracle.truffle.r.runtime.data.RList)}
+ * ).
+ * <p>
+ * The setter nodes are outlined in the following list:
+ * <ul>
+ * <li>
+ * {@link com.oracle.truffle.r.nodes.attributes.SpecialAttributesFunctions.SetClassAttributeNode}
+ * <li>{@link com.oracle.truffle.r.nodes.attributes.SpecialAttributesFunctions.SetDimAttributeNode}
+ * <li>
+ * {@link com.oracle.truffle.r.nodes.attributes.SpecialAttributesFunctions.SetDimNamesAttributeNode}
+ * <li>
+ * {@link com.oracle.truffle.r.nodes.attributes.SpecialAttributesFunctions.SetNamesAttributeNode}
+ * <li>
+ * {@link com.oracle.truffle.r.nodes.attributes.SpecialAttributesFunctions.SetRowNamesAttributeNode}
+ * </ul>
+ * For each node in the list there is a corresponding "get", "has" and "remove" counterpart.
+ * <p>
+ * When creating a fixed attribute node, one needn't take care of whether the attribute is a special
+ * one or not. The static factory methods defined on the base fixed attribute nodes take care of
+ * that and create the corresponding instance as long as the attribute is a special one. Thus, all
+ * the following initializations produce an instance of
+ * {@link com.oracle.truffle.r.nodes.attributes.SpecialAttributesFunctions.SetDimAttributeNode}.
+ *
+ * <pre>
+ * &#64;Child private SetFixedAttributeNode setDimNode = SetFixedAttributeNode.create("dim");
+ * &#64;Child private SetFixedAttributeNode setDimNode = SetFixedAttributeNode.create(RRuntime.DIM_ATTR_KEY);
+ * &#64;Child private SetFixedAttributeNode setDimNode = SetFixedAttributeNode.createDim();
+ * &#64;Child private SetFixedAttributeNode setDimNode = SetDimAttributeNode.create();
+ * </pre>
+ *
+ * Similarly, one does not need to take care of the special attributes when accessing arbitrary
+ * attributes in an attributable instance. As shown in the following snippet, the arbitrary
+ * attribute node recognizes a potential special attribute and handles it appropriately.
+ * <p>
+ * N.B. This mechanism works for instances of
+ * {@link com.oracle.truffle.r.runtime.data.RAttributable} only.
+ *
+ * <pre>
+ * &#64;Child
+ * private SetFixedAttributeNode setAttrNode = SetAttributeNode.create();
+ *
+ * &#64;Specialization
+ * protected Object handleStringVector(RAbstractStringVector v, String attrName, Object attrValue) {
+ *    ...
+ *    setAttrNode.execute(vector, attrName, attrValue);
+ *    ...
+ * }
+ * </pre>
+ *
+ * <h3>Iterative nodes</h3> There are two nodes returning iterable instances. The elements returned
+ * by those objects are instances of
+ * {@link com.oracle.truffle.r.runtime.data.RAttributesLayout.RAttribute}.
+ * <ul>
+ * <li>{@link com.oracle.truffle.r.nodes.attributes.ArrayAttributeNode}
+ * <li>{@link com.oracle.truffle.r.nodes.attributes.IterableAttributeNode}
+ * </ul>
+ * The above-mentioned nodes always return a non-null instance, even if an attributable instance has
+ * no attributes.
+ *
+ * <pre>
+ * &#64;Child private IterableAttributeNode iterAttrAccess = IterableAttributeNode.create();
+ *
+ * &#64;Specialization
+ * protected Object handleStringVector(RAbstractStringVector v) {
+ *    ...
+ *    for (RAttribute a : iterAttrAccess.execute(v)) {
+ *      if ("foo".equals(a.getName())) {
+ *          ...
+ *      }
+ *    }
+ *    ...
+ * }
+ * </pre>
+ *
+ */
+package com.oracle.truffle.r.nodes.attributes;
diff --git a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/binary/BinaryBooleanScalarNode.java b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/binary/BinaryBooleanScalarNode.java
index 00fd37061cd9548111df37b17ddf621dea0401ca..3a3f0fe6d7477ce2aa7426dd4c7ae506f7867b8e 100644
--- a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/binary/BinaryBooleanScalarNode.java
+++ b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/binary/BinaryBooleanScalarNode.java
@@ -23,7 +23,6 @@
 package com.oracle.truffle.r.nodes.binary;
 
 import com.oracle.truffle.api.CompilerAsserts;
-import com.oracle.truffle.api.CompilerDirectives;
 import com.oracle.truffle.api.CompilerDirectives.TruffleBoundary;
 import com.oracle.truffle.api.dsl.Cached;
 import com.oracle.truffle.api.dsl.Fallback;
@@ -65,26 +64,19 @@ public abstract class BinaryBooleanScalarNode extends RBuiltinNode {
 
     BinaryBooleanScalarNode(BooleanOperationFactory factory) {
         this.booleanLogic = factory.createOperation();
+        logic = new BinaryMapBooleanFunctionNode(booleanLogic);
+        leftCast = LogicalScalarCastNodeGen.create(booleanLogic.opName(), "x", logic.getLeftNACheck());
+        leftBox = BoxPrimitiveNodeGen.create();
+        rightCast = LogicalScalarCastNodeGen.create(booleanLogic.opName(), "y", logic.getRightNACheck());
+        rightBox = BoxPrimitiveNodeGen.create();
+        promiseHelper = new PromiseCheckHelperNode();
     }
 
     @Specialization
     protected byte binary(VirtualFrame frame, Object leftValue, Object rightValue) {
-        if (leftCast == null) {
-            CompilerDirectives.transferToInterpreterAndInvalidate();
-            logic = insert(new BinaryMapBooleanFunctionNode(booleanLogic));
-            leftCast = insert(LogicalScalarCastNodeGen.create(booleanLogic.opName(), "x", logic.getLeftNACheck()));
-            leftBox = insert(BoxPrimitiveNodeGen.create());
-        }
         byte left = leftCast.executeCast(leftBox.execute(leftValue));
         if (profile.profile(logic.requiresRightOperand(left))) {
-            if (rightCast == null) {
-                CompilerDirectives.transferToInterpreterAndInvalidate();
-                rightCast = insert(LogicalScalarCastNodeGen.create(booleanLogic.opName(), "y", logic.getRightNACheck()));
-                rightBox = insert(BoxPrimitiveNodeGen.create());
-                promiseHelper = insert(new PromiseCheckHelperNode());
-            }
-            byte right = rightCast.executeCast(rightBox.execute(promiseHelper.checkEvaluate(frame, rightValue)));
-            return logic.applyLogical(left, right);
+            return logic.applyLogical(left, rightCast.executeCast(rightBox.execute(promiseHelper.checkEvaluate(frame, rightValue))));
         }
         return left;
     }
diff --git a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/builtin/RBuiltinRootNode.java b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/builtin/RBuiltinRootNode.java
index ea86da6f090ada1bea4c02162a1939ddb0e4f6df..9e0044e2416661076963972c25b27bc29069cfbd 100644
--- a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/builtin/RBuiltinRootNode.java
+++ b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/builtin/RBuiltinRootNode.java
@@ -48,7 +48,7 @@ public final class RBuiltinRootNode extends RRootNode {
     private final RBuiltinFactory factory;
 
     RBuiltinRootNode(RBuiltinFactory factory, RBuiltinNode builtin, FormalArguments formalArguments, FrameDescriptor frameDescriptor, FastPathFactory fastPath) {
-        super(null, formalArguments, frameDescriptor, fastPath);
+        super(formalArguments, frameDescriptor, fastPath);
         this.factory = factory;
         this.builtin = builtin;
         this.args = new AccessArgumentNode[factory.getSignature().getLength()];
@@ -89,7 +89,7 @@ public final class RBuiltinRootNode extends RRootNode {
             throw new RInternalError(e, "internal error");
         } finally {
             visibility.execute(frame, factory.getVisibility());
-            visibility.executeEndOfFunction(frame);
+            visibility.executeEndOfFunction(frame, this);
         }
     }
 
@@ -121,9 +121,4 @@ public final class RBuiltinRootNode extends RRootNode {
     public String getName() {
         return "RBuiltin(" + builtin + ")";
     }
-
-    @Override
-    public String toString() {
-        return getName();
-    }
 }
diff --git a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/control/ParNode.java b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/control/ParNode.java
deleted file mode 100644
index ba7c6cf1f0794ea981d138894c8350c3f87ef35e..0000000000000000000000000000000000000000
--- a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/control/ParNode.java
+++ /dev/null
@@ -1,69 +0,0 @@
-/*
- * Copyright (c) 2015, 2016, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-package com.oracle.truffle.r.nodes.control;
-
-import com.oracle.truffle.api.frame.VirtualFrame;
-import com.oracle.truffle.api.source.SourceSection;
-import com.oracle.truffle.r.nodes.function.visibility.SetVisibilityNode;
-import com.oracle.truffle.r.runtime.ArgumentsSignature;
-import com.oracle.truffle.r.runtime.nodes.RNode;
-import com.oracle.truffle.r.runtime.nodes.RSyntaxLookup;
-import com.oracle.truffle.r.runtime.nodes.RSyntaxNode;
-
-/**
- * A {@link ParNode} represents parentheses in source code.
- */
-public final class ParNode extends OperatorNode {
-
-    @Child private RNode value;
-    @Child private SetVisibilityNode visibility = SetVisibilityNode.create();
-
-    public ParNode(SourceSection src, RSyntaxLookup operator, RSyntaxNode value) {
-        super(src, operator);
-        this.value = value.asRNode();
-    }
-
-    @Override
-    public Object execute(VirtualFrame frame) {
-        try {
-            return value.execute(frame);
-        } finally {
-            visibility.execute(frame, true);
-        }
-    }
-
-    @Override
-    public void voidExecute(VirtualFrame frame) {
-        value.voidExecute(frame);
-    }
-
-    @Override
-    public RSyntaxNode[] getSyntaxArguments() {
-        return new RSyntaxNode[]{value.asRSyntaxNode()};
-    }
-
-    @Override
-    public ArgumentsSignature getSyntaxSignature() {
-        return ArgumentsSignature.empty(1);
-    }
-}
diff --git a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/control/ReplacementDispatchNode.java b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/control/ReplacementDispatchNode.java
index 396fd5c39cffee2274f1ad97d3d5a7bdea709d95..87aa63e674b51eae64d265e3303944c8e4d1dd35 100644
--- a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/control/ReplacementDispatchNode.java
+++ b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/control/ReplacementDispatchNode.java
@@ -84,7 +84,7 @@ public final class ReplacementDispatchNode extends OperatorNode {
 
     public RNode create(boolean isVoid) {
         RNode replacement;
-        if (lhs instanceof RSyntaxCall) {
+        if (lhs.asRSyntaxNode() instanceof RSyntaxCall) {
             replacement = createReplacementNode(isVoid);
         } else {
             replacement = new WriteVariableSyntaxNode(getLazySourceSection(), operator, lhs.asRSyntaxNode(), rhs, isSuper);
diff --git a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/control/ReplacementNode.java b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/control/ReplacementNode.java
index 936e2babd89f1a40e0485779285835a07c622653..8fea3922499d8129309a55a96d5a685689993d7a 100644
--- a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/control/ReplacementNode.java
+++ b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/control/ReplacementNode.java
@@ -69,6 +69,10 @@ abstract class ReplacementNode extends OperatorNode {
         // Note: if specials are turned off in FastR, onlySpecials will never be true
         boolean createSpecial = hasOnlySpecialCalls(calls);
         if (createSpecial) {
+            /*
+             * This assumes that whenever there's a special call for the "extract", there's also a
+             * special call for "replace".
+             */
             if (isVoid) {
                 return new SpecialVoidReplacementNode(source, operator, target, lhs, rhs, calls, targetVarName, isSuper, tempNamesStartIndex);
             } else {
diff --git a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/function/ArgumentStatePush.java b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/function/ArgumentStatePush.java
index 3e3347bf7972c9421593be2388be054e9a88a0bc..6100faa0f41002be34f10714130b93693fffade9 100644
--- a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/function/ArgumentStatePush.java
+++ b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/function/ArgumentStatePush.java
@@ -24,25 +24,33 @@ package com.oracle.truffle.r.nodes.function;
 
 import com.oracle.truffle.api.CompilerDirectives;
 import com.oracle.truffle.api.CompilerDirectives.CompilationFinal;
+import com.oracle.truffle.api.dsl.Cached;
 import com.oracle.truffle.api.dsl.Specialization;
+import com.oracle.truffle.api.dsl.TypeSystemReference;
 import com.oracle.truffle.api.frame.VirtualFrame;
 import com.oracle.truffle.api.nodes.Node;
 import com.oracle.truffle.api.profiles.ConditionProfile;
+import com.oracle.truffle.r.nodes.EmptyTypeSystemFlatLayout;
 import com.oracle.truffle.r.nodes.access.WriteLocalFrameVariableNode;
 import com.oracle.truffle.r.runtime.FastROptions;
 import com.oracle.truffle.r.runtime.RArguments;
+import com.oracle.truffle.r.runtime.RInternalError;
 import com.oracle.truffle.r.runtime.data.RFunction;
 import com.oracle.truffle.r.runtime.data.RLanguage;
 import com.oracle.truffle.r.runtime.data.RShareable;
+import com.oracle.truffle.r.runtime.data.RSharingAttributeStorage;
 import com.oracle.truffle.r.runtime.data.model.RAbstractContainer;
 
 /**
  * A {@link ArgumentStatePush} is used to bump up state transition for function arguments.
  */
+@TypeSystemReference(EmptyTypeSystemFlatLayout.class)
 public abstract class ArgumentStatePush extends Node {
 
     public abstract void executeObject(VirtualFrame frame, Object shareable);
 
+    @Child private WriteLocalFrameVariableNode write;
+
     private final ConditionProfile isRefCountUpdateable = ConditionProfile.createBinaryProfile();
 
     private final int index;
@@ -57,76 +65,59 @@ public abstract class ArgumentStatePush extends Node {
         this.index = index;
     }
 
-    public boolean refCounted() {
-        return mask > 0;
+    protected int createWriteArgMask(VirtualFrame frame, RShareable shareable) {
+        if (shareable instanceof RAbstractContainer) {
+            if (shareable instanceof RLanguage || ((RAbstractContainer) shareable).getLength() < REF_COUNT_SIZE_THRESHOLD) {
+                // don't decrement ref count for small objects or language objects- this
+                // is pretty conservative and can be further finessed
+                return -1;
+            }
+        }
+        RFunction fun = RArguments.getFunction(frame);
+        if (fun == null) {
+            return -1;
+        }
+        Object root = fun.getRootNode();
+        if (!(root instanceof FunctionDefinitionNode)) {
+            // root is RBuiltinRootNode
+            return -1;
+        }
+        FunctionDefinitionNode fdn = (FunctionDefinitionNode) root;
+        PostProcessArgumentsNode postProcessNode = fdn.getArgPostProcess();
+        if (postProcessNode == null) {
+            // arguments to this function are not to be reference counted
+            return -1;
+        }
+        if (!postProcessNode.updateBits(index)) {
+            // this will fail if the index is too big
+            return -1;
+        }
+        return 1 << index;
     }
 
     @Specialization
-    public void transitionState(VirtualFrame frame, RShareable shareable) {
+    public void transitionState(VirtualFrame frame, RSharingAttributeStorage shareable,
+                    @Cached("createWriteArgMask(frame, shareable)") int writeArgMask) {
         if (isRefCountUpdateable.profile(!shareable.isSharedPermanent())) {
             shareable.incRefCount();
-            if (!FastROptions.RefCountIncrementOnly.getBooleanValue()) {
-                if (mask == 0) {
+            if (writeArgMask != -1 && !FastROptions.RefCountIncrementOnly.getBooleanValue()) {
+                if (write == null) {
                     CompilerDirectives.transferToInterpreterAndInvalidate();
-                    if (shareable instanceof RAbstractContainer) {
-                        if (shareable instanceof RLanguage || ((RAbstractContainer) shareable).getLength() < REF_COUNT_SIZE_THRESHOLD) {
-                            // don't decrement ref count for small objects or language objects- this
-                            // is
-                            // pretty conservative and can be further finessed
-                            mask = -1;
-                            return;
-                        }
-                    }
-                    RFunction fun = RArguments.getFunction(frame);
-                    if (fun == null) {
-                        mask = -1;
-                        return;
-                    }
-                    Object root = fun.getRootNode();
-                    if (!(root instanceof FunctionDefinitionNode)) {
-                        // root is RBuiltinRootNode
-                        mask = -1;
-                        return;
-                    }
-                    FunctionDefinitionNode fdn = (FunctionDefinitionNode) root;
-                    PostProcessArgumentsNode postProcessNode = fdn.getArgPostProcess();
-                    if (postProcessNode == null) {
-                        // arguments to this function are not to be reference counted
-                        mask = -1;
-                        return;
-                    }
-                    // this is needed for when FunctionDefinitionNode is split by the Truffle
-                    // runtime
-                    postProcessNode = postProcessNode.getActualNode();
-                    if (index >= Math.min(postProcessNode.getLength(), MAX_COUNTED_ARGS)) {
-                        mask = -1;
-                        return;
-                    }
-                    mask = 1 << index;
-                    int transArgsBitSet = postProcessNode.transArgsBitSet;
-                    postProcessNode.transArgsBitSet = transArgsBitSet | mask;
-                    writeArgNode = insert(WriteLocalFrameVariableNode.createForRefCount(Integer.valueOf(mask)));
-                }
-                if (mask != -1) {
-                    writeArgNode.execute(frame, shareable);
+                    write = insert(WriteLocalFrameVariableNode.createForRefCount(Integer.valueOf(writeArgMask)));
                 }
+                write.execute(frame, shareable);
             }
         }
     }
 
+    @Specialization
+    public void transitionState(RShareable shareable) {
+        throw RInternalError.shouldNotReachHere("unexpected RShareable that is not RSharingAttributeStorage: " + shareable.getClass());
+    }
+
     @Specialization(guards = "!isShareable(o)")
-    public void transitionStateNonShareable(VirtualFrame frame, @SuppressWarnings("unused") Object o) {
-        if (mask > 0) {
-            // this argument used to be reference counted but is no longer
-            CompilerDirectives.transferToInterpreterAndInvalidate();
-            RFunction fun = RArguments.getFunction(frame);
-            assert fun != null;
-            FunctionDefinitionNode fdn = (FunctionDefinitionNode) fun.getRootNode();
-            assert fdn != null;
-            int transArgsBitSet = fdn.getArgPostProcess().transArgsBitSet;
-            fdn.getArgPostProcess().transArgsBitSet = transArgsBitSet & (~mask);
-            mask = -1;
-        }
+    public void transitionStateNonShareable(@SuppressWarnings("unused") Object o) {
+        // do nothing
     }
 
     protected boolean isShareable(Object o) {
diff --git a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/function/CallArgumentsNode.java b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/function/CallArgumentsNode.java
index 6359e94caa2fbf0e94bdf95af98c5b7dc4633ace..818244e964bd14a74c07476e39b4bb09d00706fa 100644
--- a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/function/CallArgumentsNode.java
+++ b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/function/CallArgumentsNode.java
@@ -161,8 +161,18 @@ public final class CallArgumentsNode extends RBaseNode implements UnmatchedArgum
         return Arguments.create(values, ArgumentsSignature.get(newNames));
     }
 
-    private ArgumentsSignature cachedVarArgsSignature;
-    private ArgumentsSignature cachedResultSignature;
+    private static final class CachedSignature {
+        private final ArgumentsSignature signature;
+        private final ArgumentsSignature resultSignature;
+
+        protected CachedSignature(ArgumentsSignature signature, ArgumentsSignature resultSignature) {
+            this.signature = signature;
+            this.resultSignature = resultSignature;
+        }
+    }
+
+    private CachedSignature cachedVarArgsSignature;
+
     private final BranchProfile regenerateSignatureProfile = BranchProfile.create();
 
     public ArgumentsSignature flattenNames(RArgsValuesAndNames varArgs) {
@@ -170,15 +180,15 @@ public final class CallArgumentsNode extends RBaseNode implements UnmatchedArgum
             return signature;
         }
         ArgumentsSignature varArgsSignature = varArgs.getSignature();
-        if (cachedVarArgsSignature == null) {
+        CachedSignature cached = cachedVarArgsSignature;
+        if (cached == null) {
             CompilerDirectives.transferToInterpreter();
         }
-        if (varArgsSignature == cachedVarArgsSignature) {
-            return cachedResultSignature;
+        if (cached == null || varArgsSignature != cached.signature) {
+            regenerateSignatureProfile.enter();
+            cachedVarArgsSignature = cached = new CachedSignature(varArgsSignature, flattenNamesInternal(varArgsSignature));
         }
-        regenerateSignatureProfile.enter();
-        cachedVarArgsSignature = varArgsSignature;
-        return cachedResultSignature = flattenNamesInternal(varArgsSignature);
+        return cached.resultSignature;
     }
 
     @TruffleBoundary
diff --git a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/function/CallMatcherNode.java b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/function/CallMatcherNode.java
index 9454d1b46b985707c8c836d1c714a9b1b86936e3..e034cfa67da52aab6d8a18ab88da0b95344e6a95 100644
--- a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/function/CallMatcherNode.java
+++ b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/function/CallMatcherNode.java
@@ -60,7 +60,7 @@ public abstract class CallMatcherNode extends RBaseNode {
     private static final int MAX_CACHE_DEPTH = 3;
 
     public static CallMatcherNode create(boolean argsAreEvaluated) {
-        return new CallMatcherUninitializedNode(argsAreEvaluated);
+        return new CallMatcherUninitializedNode(argsAreEvaluated, 0);
     }
 
     public abstract Object execute(VirtualFrame frame, ArgumentsSignature suppliedSignature, Object[] suppliedArguments, RFunction function, String functionName, DispatchArgs dispatchArgs);
@@ -151,19 +151,20 @@ public abstract class CallMatcherNode extends RBaseNode {
 
     @NodeInfo(cost = NodeCost.UNINITIALIZED)
     private static final class CallMatcherUninitializedNode extends CallMatcherNode {
-        CallMatcherUninitializedNode(boolean argsAreEvaluated) {
+        CallMatcherUninitializedNode(boolean argsAreEvaluated, int depth) {
             super(argsAreEvaluated);
+            this.depth = depth;
         }
 
-        private int depth;
+        private final int depth;
 
         @Override
         public Object execute(VirtualFrame frame, ArgumentsSignature suppliedSignature, Object[] suppliedArguments, RFunction function, String functionName, DispatchArgs dispatchArgs) {
             CompilerDirectives.transferToInterpreterAndInvalidate();
-            if (++depth > MAX_CACHE_DEPTH) {
+            if (depth > MAX_CACHE_DEPTH) {
                 return replace(new CallMatcherGenericNode(argsAreEvaluated)).execute(frame, suppliedSignature, suppliedArguments, function, functionName, dispatchArgs);
             } else {
-                CallMatcherCachedNode cachedNode = replace(specialize(suppliedSignature, suppliedArguments, function, this));
+                CallMatcherCachedNode cachedNode = replace(specialize(suppliedSignature, suppliedArguments, function, new CallMatcherUninitializedNode(argsAreEvaluated, depth + 1)));
                 // for splitting if necessary
                 if (cachedNode.call != null && RCallNode.needsSplitting(function.getTarget())) {
                     cachedNode.call.getCallNode().cloneCallTarget();
diff --git a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/function/ClassHierarchyNode.java b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/function/ClassHierarchyNode.java
index e397c96de1f4aef834dc7a454723b3325de7ef7c..14e18c0155505da31caab95ef8bd77c832173ecc 100644
--- a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/function/ClassHierarchyNode.java
+++ b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/function/ClassHierarchyNode.java
@@ -40,7 +40,6 @@ import com.oracle.truffle.r.nodes.unary.CastToVectorNode;
 import com.oracle.truffle.r.nodes.unary.UnaryNode;
 import com.oracle.truffle.r.runtime.RCaller;
 import com.oracle.truffle.r.runtime.RInternalError;
-import com.oracle.truffle.r.runtime.Utils;
 import com.oracle.truffle.r.runtime.context.RContext;
 import com.oracle.truffle.r.runtime.data.RArgsValuesAndNames;
 import com.oracle.truffle.r.runtime.data.RAttributable;
@@ -188,8 +187,7 @@ abstract class S4Class extends RBaseNode {
             // the assumption here is that the R function can only return either a String or
             // RStringVector
             s4Extends = (RStringVector) castToVector.execute(
-                            RContext.getEngine().evalFunction(sExtendsForS3Function, methodsEnv.getFrame(), RCaller.create(Utils.getActualCurrentFrame(), RASTUtils.getOriginalCall(this)), null,
-                                            classAttr));
+                            RContext.getEngine().evalFunction(sExtendsForS3Function, methodsEnv.getFrame(), RCaller.create(null, RASTUtils.getOriginalCall(this)), null, classAttr));
             RContext.getInstance().putS4Extends(classAttr, s4Extends);
         }
         return s4Extends;
diff --git a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/function/FunctionDefinitionNode.java b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/function/FunctionDefinitionNode.java
index 4a2c89ad48a62fc5debd7c6be8f4bb3ca2864f8e..e2019c4c78506fca390f3b711385e08ee8b1d999 100644
--- a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/function/FunctionDefinitionNode.java
+++ b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/function/FunctionDefinitionNode.java
@@ -25,11 +25,14 @@ package com.oracle.truffle.r.nodes.function;
 import java.util.ArrayList;
 import java.util.List;
 
+import com.oracle.truffle.api.Assumption;
 import com.oracle.truffle.api.CompilerDirectives;
 import com.oracle.truffle.api.CompilerDirectives.CompilationFinal;
 import com.oracle.truffle.api.RootCallTarget;
+import com.oracle.truffle.api.Truffle;
 import com.oracle.truffle.api.frame.FrameDescriptor;
 import com.oracle.truffle.api.frame.FrameSlot;
+import com.oracle.truffle.api.frame.FrameSlotKind;
 import com.oracle.truffle.api.frame.FrameSlotTypeException;
 import com.oracle.truffle.api.frame.VirtualFrame;
 import com.oracle.truffle.api.nodes.Node;
@@ -101,28 +104,22 @@ public final class FunctionDefinitionNode extends RRootNode implements RSyntaxNo
     private final BranchProfile breakProfile = BranchProfile.create();
     private final BranchProfile nextProfile = BranchProfile.create();
 
-    @CompilationFinal private BranchProfile invalidateFrameSlotProfile;
-    // S3/S4 slots
-    @Child private FrameSlotNode dotGenericSlot;
-    @Child private FrameSlotNode dotMethodSlot;
-    // S3 slots
-    @Child private FrameSlotNode dotClassSlot;
-    @Child private FrameSlotNode dotGenericCallEnvSlot;
-    @Child private FrameSlotNode dotGenericCallDefSlot;
-    @Child private FrameSlotNode dotGroupSlot;
-    // S4 slots
-    @Child private FrameSlotNode dotDefinedSlot;
-    @Child private FrameSlotNode dotTargetSlot;
-    @Child private FrameSlotNode dotMethodsSlot;
-
     @Child private SetVisibilityNode visibility = SetVisibilityNode.create();
 
     @Child private PostProcessArgumentsNode argPostProcess;
 
+    @Child private SetupS3ArgsNode setupS3Args;
+    @Child private SetupS4ArgsNode setupS4Args;
+
     private final boolean needsSplitting;
 
     @CompilationFinal private boolean containsDispatch;
 
+    private final Assumption noHandlerStackSlot = Truffle.getRuntime().createAssumption();
+    private final Assumption noRestartStackSlot = Truffle.getRuntime().createAssumption();
+    @CompilationFinal private FrameSlot handlerStackSlot;
+    @CompilationFinal private FrameSlot restartStackSlot;
+
     /**
      * Profiling for catching {@link ReturnException}s.
      */
@@ -135,7 +132,7 @@ public final class FunctionDefinitionNode extends RRootNode implements RSyntaxNo
 
     private FunctionDefinitionNode(SourceSection src, FrameDescriptor frameDesc, SourceSection[] argSourceSections, RNode saveArguments, RSyntaxNode body, FormalArguments formals,
                     String name, PostProcessArgumentsNode argPostProcess) {
-        super(null, formals, frameDesc, RASTBuilder.createFunctionFastPath(body, formals.getSignature()));
+        super(formals, frameDesc, RASTBuilder.createFunctionFastPath(body, formals.getSignature()));
         this.argSourceSections = argSourceSections;
         assert FrameSlotChangeMonitor.isValidFrameDescriptor(frameDesc);
         assert src != null;
@@ -239,12 +236,6 @@ public final class FunctionDefinitionNode extends RRootNode implements RSyntaxNo
 
     @Override
     public Object execute(VirtualFrame frame) {
-        /*
-         * It might be possible to only record this iff a handler is installed, by using the
-         * RArguments array.
-         */
-        Object handlerStack = RErrorHandling.getHandlerStack();
-        Object restartStack = RErrorHandling.getRestartStack();
         boolean runOnExitHandlers = true;
         try {
             verifyEnclosingAssumptions(frame);
@@ -288,13 +279,27 @@ public final class FunctionDefinitionNode extends RRootNode implements RSyntaxNo
              * has no exit handlers (by fiat), so any exceptions from onExits handlers will be
              * caught above.
              */
-            visibility.executeEndOfFunction(frame);
+            visibility.executeEndOfFunction(frame, this);
             if (argPostProcess != null) {
                 resetArgs.enter();
                 argPostProcess.execute(frame);
             }
             if (runOnExitHandlers) {
-                RErrorHandling.restoreStacks(handlerStack, restartStack);
+                if (!noHandlerStackSlot.isValid() && frame.isObject(handlerStackSlot)) {
+                    try {
+                        RErrorHandling.restoreHandlerStack(frame.getObject(handlerStackSlot));
+                    } catch (FrameSlotTypeException e) {
+                        throw RInternalError.shouldNotReachHere();
+                    }
+                }
+                if (!noRestartStackSlot.isValid() && frame.isObject(restartStackSlot)) {
+                    try {
+                        RErrorHandling.restoreRestartStack(frame.getObject(restartStackSlot));
+                    } catch (FrameSlotTypeException e) {
+                        throw RInternalError.shouldNotReachHere();
+                    }
+                }
+
                 if (onExitProfile.profile(onExitSlot.hasValue(frame))) {
                     if (onExitExpressionCache == null) {
                         CompilerDirectives.transferToInterpreterAndInvalidate();
@@ -317,55 +322,88 @@ public final class FunctionDefinitionNode extends RRootNode implements RSyntaxNo
         }
     }
 
+    private abstract static class SetupDispatchNode extends Node {
+        // S3/S4 slots
+        private final FrameSlot dotGenericSlot;
+        private final FrameSlot dotMethodSlot;
+
+        final BranchProfile invalidateFrameSlotProfile = BranchProfile.create();
+
+        SetupDispatchNode(FrameDescriptor frameDescriptor) {
+            dotGenericSlot = FrameSlotChangeMonitor.findOrAddFrameSlot(frameDescriptor, RRuntime.R_DOT_GENERIC, FrameSlotKind.Object);
+            dotMethodSlot = FrameSlotChangeMonitor.findOrAddFrameSlot(frameDescriptor, RRuntime.R_DOT_METHOD, FrameSlotKind.Object);
+        }
+
+        void execute(VirtualFrame frame, DispatchArgs args) {
+            FrameSlotChangeMonitor.setObjectAndInvalidate(frame, dotGenericSlot, args.generic, false, invalidateFrameSlotProfile);
+            FrameSlotChangeMonitor.setObjectAndInvalidate(frame, dotMethodSlot, args.method, false, invalidateFrameSlotProfile);
+        }
+    }
+
+    private static final class SetupS3ArgsNode extends SetupDispatchNode {
+        // S3 slots
+        private final FrameSlot dotClassSlot;
+        private final FrameSlot dotGenericCallEnvSlot;
+        private final FrameSlot dotGenericCallDefSlot;
+        private final FrameSlot dotGroupSlot;
+
+        SetupS3ArgsNode(FrameDescriptor frameDescriptor) {
+            super(frameDescriptor);
+            dotClassSlot = FrameSlotChangeMonitor.findOrAddFrameSlot(frameDescriptor, RRuntime.R_DOT_CLASS, FrameSlotKind.Object);
+            dotGenericCallEnvSlot = FrameSlotChangeMonitor.findOrAddFrameSlot(frameDescriptor, RRuntime.R_DOT_GENERIC_CALL_ENV, FrameSlotKind.Object);
+            dotGenericCallDefSlot = FrameSlotChangeMonitor.findOrAddFrameSlot(frameDescriptor, RRuntime.R_DOT_GENERIC_DEF_ENV, FrameSlotKind.Object);
+            dotGroupSlot = FrameSlotChangeMonitor.findOrAddFrameSlot(frameDescriptor, RRuntime.R_DOT_GROUP, FrameSlotKind.Object);
+        }
+
+        void execute(VirtualFrame frame, S3Args args) {
+            super.execute(frame, args);
+            FrameSlotChangeMonitor.setObjectAndInvalidate(frame, dotClassSlot, args.clazz, false, invalidateFrameSlotProfile);
+            FrameSlotChangeMonitor.setObjectAndInvalidate(frame, dotGenericCallEnvSlot, args.callEnv, false, invalidateFrameSlotProfile);
+            FrameSlotChangeMonitor.setObjectAndInvalidate(frame, dotGenericCallDefSlot, args.defEnv, false, invalidateFrameSlotProfile);
+            FrameSlotChangeMonitor.setObjectAndInvalidate(frame, dotGroupSlot, args.group, false, invalidateFrameSlotProfile);
+        }
+    }
+
+    private static final class SetupS4ArgsNode extends SetupDispatchNode {
+        // S4 slots
+        private final FrameSlot dotDefinedSlot;
+        private final FrameSlot dotTargetSlot;
+        private final FrameSlot dotMethodsSlot;
+
+        SetupS4ArgsNode(FrameDescriptor frameDescriptor) {
+            super(frameDescriptor);
+            dotDefinedSlot = FrameSlotChangeMonitor.findOrAddFrameSlot(frameDescriptor, RRuntime.R_DOT_DEFINED, FrameSlotKind.Object);
+            dotTargetSlot = FrameSlotChangeMonitor.findOrAddFrameSlot(frameDescriptor, RRuntime.R_DOT_TARGET, FrameSlotKind.Object);
+            dotMethodsSlot = FrameSlotChangeMonitor.findOrAddFrameSlot(frameDescriptor, RRuntime.R_DOT_METHODS, FrameSlotKind.Object);
+        }
+
+        void execute(VirtualFrame frame, S4Args args) {
+            super.execute(frame, args);
+            FrameSlotChangeMonitor.setObjectAndInvalidate(frame, dotDefinedSlot, args.defined, false, invalidateFrameSlotProfile);
+            FrameSlotChangeMonitor.setObjectAndInvalidate(frame, dotTargetSlot, args.target, false, invalidateFrameSlotProfile);
+            FrameSlotChangeMonitor.setObjectAndInvalidate(frame, dotMethodsSlot, args.methods, false, invalidateFrameSlotProfile);
+        }
+    }
+
     private void setupDispatchSlots(VirtualFrame frame) {
         DispatchArgs dispatchArgs = RArguments.getDispatchArgs(frame);
         if (dispatchArgs == null) {
             return;
         }
-        if (dotGenericSlot == null) {
-            CompilerDirectives.transferToInterpreterAndInvalidate();
-            assert invalidateFrameSlotProfile == null && dotMethodSlot == null;
-            invalidateFrameSlotProfile = BranchProfile.create();
-            FrameDescriptor frameDescriptor = frame.getFrameDescriptor();
-
-            dotGenericSlot = insert(FrameSlotNode.createInitialized(frameDescriptor, RRuntime.R_DOT_GENERIC, true));
-            dotMethodSlot = insert(FrameSlotNode.createInitialized(frameDescriptor, RRuntime.R_DOT_METHOD, true));
-        }
-        FrameSlotChangeMonitor.setObjectAndInvalidate(frame, dotGenericSlot.executeFrameSlot(frame), dispatchArgs.generic, false, invalidateFrameSlotProfile);
-        FrameSlotChangeMonitor.setObjectAndInvalidate(frame, dotMethodSlot.executeFrameSlot(frame), dispatchArgs.method, false, invalidateFrameSlotProfile);
-
         if (dispatchArgs instanceof S3Args) {
             S3Args s3Args = (S3Args) dispatchArgs;
-            if (dotClassSlot == null) {
+            if (setupS3Args == null) {
                 CompilerDirectives.transferToInterpreterAndInvalidate();
-                assert dotGenericCallEnvSlot == null && dotGenericCallDefSlot == null && dotGroupSlot == null;
-                invalidateFrameSlotProfile = BranchProfile.create();
-                FrameDescriptor frameDescriptor = frame.getFrameDescriptor();
-
-                dotClassSlot = insert(FrameSlotNode.createInitialized(frameDescriptor, RRuntime.R_DOT_CLASS, true));
-                dotGenericCallEnvSlot = insert(FrameSlotNode.createInitialized(frameDescriptor, RRuntime.R_DOT_GENERIC_CALL_ENV, true));
-                dotGenericCallDefSlot = insert(FrameSlotNode.createInitialized(frameDescriptor, RRuntime.R_DOT_GENERIC_DEF_ENV, true));
-                dotGroupSlot = insert(FrameSlotNode.createInitialized(frameDescriptor, RRuntime.R_DOT_GROUP, true));
+                setupS3Args = insert(new SetupS3ArgsNode(frame.getFrameDescriptor()));
             }
-            FrameSlotChangeMonitor.setObjectAndInvalidate(frame, dotClassSlot.executeFrameSlot(frame), s3Args.clazz, false, invalidateFrameSlotProfile);
-            FrameSlotChangeMonitor.setObjectAndInvalidate(frame, dotGenericCallEnvSlot.executeFrameSlot(frame), s3Args.callEnv, false, invalidateFrameSlotProfile);
-            FrameSlotChangeMonitor.setObjectAndInvalidate(frame, dotGenericCallDefSlot.executeFrameSlot(frame), s3Args.defEnv, false, invalidateFrameSlotProfile);
-            FrameSlotChangeMonitor.setObjectAndInvalidate(frame, dotGroupSlot.executeFrameSlot(frame), s3Args.group, false, invalidateFrameSlotProfile);
+            setupS3Args.execute(frame, s3Args);
         } else {
             S4Args s4Args = (S4Args) dispatchArgs;
-            if (dotDefinedSlot == null) {
+            if (setupS4Args == null) {
                 CompilerDirectives.transferToInterpreterAndInvalidate();
-                assert dotTargetSlot == null && dotMethodsSlot == null;
-                invalidateFrameSlotProfile = BranchProfile.create();
-                FrameDescriptor frameDescriptor = frame.getFrameDescriptor();
-
-                dotDefinedSlot = insert(FrameSlotNode.createInitialized(frameDescriptor, RRuntime.R_DOT_DEFINED, true));
-                dotTargetSlot = insert(FrameSlotNode.createInitialized(frameDescriptor, RRuntime.R_DOT_TARGET, true));
-                dotMethodsSlot = insert(FrameSlotNode.createInitialized(frameDescriptor, RRuntime.R_DOT_METHODS, true));
+                setupS4Args = insert(new SetupS4ArgsNode(frame.getFrameDescriptor()));
             }
-            FrameSlotChangeMonitor.setObjectAndInvalidate(frame, dotDefinedSlot.executeFrameSlot(frame), s4Args.defined, false, invalidateFrameSlotProfile);
-            FrameSlotChangeMonitor.setObjectAndInvalidate(frame, dotTargetSlot.executeFrameSlot(frame), s4Args.target, false, invalidateFrameSlotProfile);
-            FrameSlotChangeMonitor.setObjectAndInvalidate(frame, dotMethodsSlot.executeFrameSlot(frame), s4Args.methods, false, invalidateFrameSlotProfile);
+            setupS4Args.execute(frame, s4Args);
         }
     }
 
@@ -383,11 +421,6 @@ public final class FunctionDefinitionNode extends RRootNode implements RSyntaxNo
         return name == null ? "<no source>" : name;
     }
 
-    @Override
-    public String toString() {
-        return getName();
-    }
-
     public void setName(String name) {
         this.name = name;
     }
@@ -437,4 +470,24 @@ public final class FunctionDefinitionNode extends RRootNode implements RSyntaxNo
     public String getSyntaxDebugName() {
         return name;
     }
+
+    public FrameSlot getRestartFrameSlot(VirtualFrame frame) {
+        if (noRestartStackSlot.isValid()) {
+            CompilerDirectives.transferToInterpreterAndInvalidate();
+            restartStackSlot = frame.getFrameDescriptor().findOrAddFrameSlot(RFrameSlot.RestartStack);
+            noRestartStackSlot.invalidate();
+        }
+        assert restartStackSlot != null;
+        return restartStackSlot;
+    }
+
+    public FrameSlot getHandlerFrameSlot(VirtualFrame frame) {
+        if (noHandlerStackSlot.isValid()) {
+            CompilerDirectives.transferToInterpreterAndInvalidate();
+            handlerStackSlot = frame.getFrameDescriptor().findOrAddFrameSlot(RFrameSlot.HandlerStack);
+            noHandlerStackSlot.invalidate();
+        }
+        assert handlerStackSlot != null;
+        return handlerStackSlot;
+    }
 }
diff --git a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/function/FunctionExpressionNode.java b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/function/FunctionExpressionNode.java
index e0c9f9eb525f116bfd2cf38921a8320f3e12bfb0..cc6676d89f3499383915a05d82b9a91b50f5cb78 100644
--- a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/function/FunctionExpressionNode.java
+++ b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/function/FunctionExpressionNode.java
@@ -32,6 +32,7 @@ import com.oracle.truffle.r.nodes.RASTUtils;
 import com.oracle.truffle.r.nodes.RRootNode;
 import com.oracle.truffle.r.nodes.function.PromiseHelperNode.PromiseDeoptimizeFrameNode;
 import com.oracle.truffle.r.nodes.function.opt.EagerEvalHelper;
+import com.oracle.truffle.r.nodes.function.visibility.SetVisibilityNode;
 import com.oracle.truffle.r.nodes.instrumentation.RInstrumentation;
 import com.oracle.truffle.r.runtime.ArgumentsSignature;
 import com.oracle.truffle.r.runtime.builtins.FastPathFactory;
@@ -49,6 +50,8 @@ public final class FunctionExpressionNode extends RSourceSectionNode implements
         return new FunctionExpressionNode(src, callTarget);
     }
 
+    @Child private SetVisibilityNode visibility = SetVisibilityNode.create();
+
     @CompilationFinal private RootCallTarget callTarget;
     private final PromiseDeoptimizeFrameNode deoptFrameNode;
     @CompilationFinal private FastPathFactory fastPath;
@@ -68,6 +71,7 @@ public final class FunctionExpressionNode extends RSourceSectionNode implements
 
     @Override
     public RFunction executeFunction(VirtualFrame frame) {
+        visibility.execute(frame, true);
         MaterializedFrame matFrame = frame.materialize();
         if (deoptFrameNode != null) {
             // Deoptimize every promise which is now in this frame, as it might leave it's stack
diff --git a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/function/PostProcessArgumentsNode.java b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/function/PostProcessArgumentsNode.java
index 70c054c22da7929dfaac6ae718dd7b1af33e3650..e808377fefc5bedf97ad147c5d5950c6cfbd272a 100644
--- a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/function/PostProcessArgumentsNode.java
+++ b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/function/PostProcessArgumentsNode.java
@@ -22,13 +22,11 @@
  */
 package com.oracle.truffle.r.nodes.function;
 
-import com.oracle.truffle.api.CompilerAsserts;
 import com.oracle.truffle.api.CompilerDirectives;
-import com.oracle.truffle.api.CompilerDirectives.CompilationFinal;
 import com.oracle.truffle.api.frame.VirtualFrame;
 import com.oracle.truffle.api.nodes.ExplodeLoop;
-import com.oracle.truffle.api.nodes.Node;
 import com.oracle.truffle.api.profiles.ConditionProfile;
+import com.oracle.truffle.api.utilities.AssumedValue;
 import com.oracle.truffle.r.nodes.access.variables.LocalReadVariableNode;
 import com.oracle.truffle.r.runtime.data.RNull;
 import com.oracle.truffle.r.runtime.data.RShareable;
@@ -41,28 +39,20 @@ import com.oracle.truffle.r.runtime.nodes.RNode;
 public final class PostProcessArgumentsNode extends RNode {
 
     @Children private final LocalReadVariableNode[] sequence;
-    @Child private PostProcessArgumentsNode nextOptPostProccessArgNode;
-    @CompilationFinal int transArgsBitSet;
 
-    // the first time this node is cloned (via FunctionDefinitionNode) it's from the trufflerizer -
-    // in this case we should not create the node chain chain in the clone operation (below) at the
-    // reference count meta data needs to be associated with this node and not its clone
-    @CompilationFinal private boolean createClone;
+    // stays the same during cloning
+    private final AssumedValue<Integer> transArgsBitSet;
+
+    private final ConditionProfile isNonNull = ConditionProfile.createBinaryProfile();
     private final ConditionProfile isRefCountUpdateable = ConditionProfile.createBinaryProfile();
 
-    private PostProcessArgumentsNode(LocalReadVariableNode[] sequence) {
-        this.sequence = sequence;
-        this.createClone = false;
-        this.transArgsBitSet = 0;
+    private PostProcessArgumentsNode(int length) {
+        this.sequence = new LocalReadVariableNode[Math.min(length, ArgumentStatePush.MAX_COUNTED_ARGS)];
+        this.transArgsBitSet = new AssumedValue<>("PostProcessArgumentsNode.transArgsBitSet", 0);
     }
 
     public static PostProcessArgumentsNode create(int length) {
-        int maxLength = Math.min(length, ArgumentStatePush.MAX_COUNTED_ARGS);
-        LocalReadVariableNode[] argReadNodes = new LocalReadVariableNode[maxLength];
-        for (int i = 0; i < maxLength; i++) {
-            argReadNodes[i] = LocalReadVariableNode.create(Integer.valueOf(1 << i), false);
-        }
-        return new PostProcessArgumentsNode(argReadNodes);
+        return new PostProcessArgumentsNode(length);
     }
 
     public int getLength() {
@@ -72,20 +62,20 @@ public final class PostProcessArgumentsNode extends RNode {
     @Override
     @ExplodeLoop
     public Object execute(VirtualFrame frame) {
-        if (transArgsBitSet > 0) {
+        int bits = transArgsBitSet.get();
+        if (bits != 0) {
             for (int i = 0; i < sequence.length; i++) {
                 int mask = 1 << i;
-                if ((transArgsBitSet & mask) == mask) {
-                    RShareable s = (RShareable) sequence[i].execute(frame);
-                    if (s == null) {
-                        // it happens rarely in compiled code, but if it does happen, stop
-                        // decrementing reference counts
+                if ((bits & mask) != 0) {
+                    if (sequence[i] == null) {
                         CompilerDirectives.transferToInterpreterAndInvalidate();
-                        transArgsBitSet = ArgumentStatePush.INVALID_INDEX;
-                        break;
+                        sequence[i] = insert(LocalReadVariableNode.create(Integer.valueOf(mask), false));
                     }
-                    if (isRefCountUpdateable.profile(!s.isSharedPermanent())) {
-                        s.decRefCount();
+                    RShareable s = (RShareable) sequence[i].execute(frame);
+                    if (isNonNull.profile(s != null)) {
+                        if (isRefCountUpdateable.profile(!s.isSharedPermanent())) {
+                            s.decRefCount();
+                        }
                     }
                 }
             }
@@ -93,38 +83,15 @@ public final class PostProcessArgumentsNode extends RNode {
         return RNull.instance;
     }
 
-    @Override
-    public Node deepCopy() {
-        CompilerAsserts.neverPartOfCompilation();
-        if (createClone) {
-            return deepCopyUnconditional();
-        } else {
-            this.createClone = true;
-            return this;
-        }
-    }
-
-    /*
-     * Deep copies are also made from other places than the trufflerizer, in which case we need to
-     * always create the node chain.
-     */
-    private PostProcessArgumentsNode deepCopyUnconditional() {
-        CompilerAsserts.neverPartOfCompilation();
-        PostProcessArgumentsNode copy = (PostProcessArgumentsNode) super.deepCopy();
-        nextOptPostProccessArgNode = insert(copy);
-        return copy;
-
-    }
-
-    PostProcessArgumentsNode getActualNode() {
-        CompilerAsserts.neverPartOfCompilation();
-        if (nextOptPostProccessArgNode == null) {
-            return this;
-        } else {
-            PostProcessArgumentsNode nextNode = nextOptPostProccessArgNode.getActualNode();
-            // shorten up the lookup chain
-            nextOptPostProccessArgNode = insert(nextNode);
-            return nextNode;
+    public boolean updateBits(int index) {
+        if (index < sequence.length) {
+            int bits = transArgsBitSet.get();
+            int newBits = bits | (1 << index);
+            if (newBits != bits) {
+                transArgsBitSet.set(newBits);
+            }
+            return true;
         }
+        return false;
     }
 }
diff --git a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/function/PromiseNode.java b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/function/PromiseNode.java
index c46789e565ff14114ae83507b1e84a267fab3d1d..e9a22756634aa1683cf6ee0403f0649c818f0869 100644
--- a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/function/PromiseNode.java
+++ b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/function/PromiseNode.java
@@ -409,8 +409,17 @@ public abstract class PromiseNode extends RNode {
         private final ConditionProfile argsValueAndNamesProfile = ConditionProfile.createBinaryProfile();
         private final ConditionProfile containsVarargProfile = ConditionProfile.createBinaryProfile();
 
-        @CompilationFinal ArgumentsSignature cachedVarArgSignature;
-        @CompilationFinal ArgumentsSignature cachedResultSignature;
+        private static final class Cache {
+            private final ArgumentsSignature signature;
+            private final ArgumentsSignature result;
+
+            protected Cache(ArgumentsSignature signature, ArgumentsSignature result) {
+                this.signature = signature;
+                this.result = result;
+            }
+        }
+
+        @CompilationFinal private Cache varArgsCache;
 
         InlineVarArgsNode(RNode[] nodes, ArgumentsSignature signature) {
             this.varargs = nodes;
@@ -455,13 +464,20 @@ public abstract class PromiseNode extends RNode {
                 if (evaluatedArgs.length == 1) {
                     finalSignature = ((RArgsValuesAndNames) evaluatedArgs[0]).getSignature();
                 } else {
-                    if (cachedVarArgSignature == ArgumentsSignature.INVALID_SIGNATURE) {
+                    Cache cache = varArgsCache;
+                    if (cache == null) {
+                        CompilerDirectives.transferToInterpreterAndInvalidate();
+                        finalSignature = createSignature(evaluatedArgs, flattenedArgs.length);
+                        varArgsCache = new Cache(varArgSignature, finalSignature);
+                    } else if (cache.signature == ArgumentsSignature.INVALID_SIGNATURE) {
                         finalSignature = createSignature(evaluatedArgs, flattenedArgs.length);
-                    } else if (varArgSignature == cachedVarArgSignature) {
-                        finalSignature = cachedResultSignature;
+                    } else if (varArgSignature == cache.signature) {
+                        finalSignature = cache.result;
                     } else {
+                        CompilerDirectives.transferToInterpreterAndInvalidate();
+                        // fallback to the generic case
                         finalSignature = createSignature(evaluatedArgs, flattenedArgs.length);
-                        cachedVarArgSignature = cachedVarArgSignature == null ? finalSignature : ArgumentsSignature.INVALID_SIGNATURE;
+                        varArgsCache = new Cache(ArgumentsSignature.INVALID_SIGNATURE, null);
                     }
                 }
                 return new RArgsValuesAndNames(flattenedArgs, finalSignature);
diff --git a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/function/RCallNode.java b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/function/RCallNode.java
index d202fe1015cfe2a332ff77da078972284f3fecf1..c7e740405648e2305d2c755dc1b4c3e23de0ca2c 100644
--- a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/function/RCallNode.java
+++ b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/function/RCallNode.java
@@ -35,6 +35,7 @@ import com.oracle.truffle.api.dsl.Fallback;
 import com.oracle.truffle.api.dsl.NodeChild;
 import com.oracle.truffle.api.dsl.Specialization;
 import com.oracle.truffle.api.dsl.TypeSystemReference;
+import com.oracle.truffle.api.frame.FrameSlot;
 import com.oracle.truffle.api.frame.FrameSlotTypeException;
 import com.oracle.truffle.api.frame.MaterializedFrame;
 import com.oracle.truffle.api.frame.VirtualFrame;
@@ -55,14 +56,12 @@ import com.oracle.truffle.r.nodes.EmptyTypeSystemFlatLayout;
 import com.oracle.truffle.r.nodes.RASTUtils;
 import com.oracle.truffle.r.nodes.RRootNode;
 import com.oracle.truffle.r.nodes.access.ConstantNode;
-import com.oracle.truffle.r.nodes.access.FrameSlotNode;
 import com.oracle.truffle.r.nodes.access.variables.LocalReadVariableNode;
 import com.oracle.truffle.r.nodes.access.variables.ReadVariableNode;
 import com.oracle.truffle.r.nodes.builtin.RBuiltinNode;
 import com.oracle.truffle.r.nodes.builtin.RBuiltinRootNode;
 import com.oracle.truffle.r.nodes.function.PromiseHelperNode.PromiseCheckHelperNode;
 import com.oracle.truffle.r.nodes.function.RCallNodeGen.FunctionDispatchNodeGen;
-import com.oracle.truffle.r.nodes.function.S3FunctionLookupNode.NoGenericMethodException;
 import com.oracle.truffle.r.nodes.function.S3FunctionLookupNode.Result;
 import com.oracle.truffle.r.nodes.function.call.CallRFunctionNode;
 import com.oracle.truffle.r.nodes.function.call.PrepareArguments;
@@ -112,23 +111,23 @@ public abstract class RCallNode extends RCallBaseNode implements RSyntaxNode, RS
 
     // currently cannot be RSourceSectionNode because of TruffleDSL restrictions
 
-    @CompilationFinal private SourceSection sourceSectionR;
+    @CompilationFinal private SourceSection sourceSection;
 
     @Override
     public final void setSourceSection(SourceSection sourceSection) {
         assert sourceSection != null;
-        this.sourceSectionR = sourceSection;
+        this.sourceSection = sourceSection;
     }
 
     @Override
     public final SourceSection getLazySourceSection() {
-        return sourceSectionR;
+        return sourceSection;
     }
 
     @Override
     public final SourceSection getSourceSection() {
         RDeparse.ensureSourceSection(this);
-        return sourceSectionR;
+        return sourceSection;
     }
 
     protected abstract ForcePromiseNode getFunction();
@@ -164,7 +163,7 @@ public abstract class RCallNode extends RCallBaseNode implements RSyntaxNode, RS
 
     protected RCallNode(SourceSection sourceSection, RSyntaxNode[] arguments, ArgumentsSignature signature) {
         assert sourceSection != null;
-        this.sourceSectionR = sourceSection;
+        this.sourceSection = sourceSection;
         this.arguments = arguments;
         this.explicitArgs = null;
         this.varArgIndexes = getVarArgIndexes(arguments);
@@ -184,7 +183,7 @@ public abstract class RCallNode extends RCallBaseNode implements RSyntaxNode, RS
 
     protected RCallNode(SourceSection sourceSection, Object explicitArgsIdentifier) {
         assert sourceSection != null;
-        this.sourceSectionR = sourceSection;
+        this.sourceSection = sourceSection;
         this.arguments = null;
         this.explicitArgs = LocalReadVariableNode.create(explicitArgsIdentifier, false);
         this.varArgIndexes = null;
@@ -234,11 +233,11 @@ public abstract class RCallNode extends RCallBaseNode implements RSyntaxNode, RS
     }
 
     protected FunctionDispatch createUninitializedCall() {
-        return FunctionDispatchNodeGen.create(this, null, explicitArgs == null ? false : true);
+        return FunctionDispatchNodeGen.create(this, explicitArgs != null, null);
     }
 
     protected FunctionDispatch createUninitializedExplicitCall() {
-        return FunctionDispatchNodeGen.create(this, null, true);
+        return FunctionDispatchNodeGen.create(this, true, null);
     }
 
     /**
@@ -284,7 +283,7 @@ public abstract class RCallNode extends RCallBaseNode implements RSyntaxNode, RS
                     @Cached("createBinaryProfile()") ConditionProfile resultIsBuiltinProfile) {
         RBuiltinDescriptor builtin = builtinProfile.profile(function.getRBuiltin());
         Object dispatchObject = dispatchArgument.execute(frame);
-        dispatchTempSlot.initialize(frame, dispatchObject, () -> internalDispatchCall = null);
+        FrameSlot slot = dispatchTempSlot.initialize(frame, dispatchObject);
         try {
             RStringVector type = classHierarchyNode.execute(dispatchObject);
             S3Args s3Args;
@@ -301,13 +300,13 @@ public abstract class RCallNode extends RCallBaseNode implements RSyntaxNode, RS
                 s3Args = null;
                 resultFunction = function;
             }
-            if (internalDispatchCall == null) {
+            if (internalDispatchCall == null || internalDispatchCall.tempFrameSlot != slot) {
                 CompilerDirectives.transferToInterpreterAndInvalidate();
-                internalDispatchCall = insert(FunctionDispatchNodeGen.create(this, new Object[]{dispatchTempSlot.getIdentifier()}, false));
+                internalDispatchCall = insert(FunctionDispatchNodeGen.create(this, false, slot));
             }
             return internalDispatchCall.execute(frame, resultFunction, lookupVarArgs(frame), s3Args, null);
         } finally {
-            dispatchTempSlot.cleanup(frame, dispatchObject);
+            TemporarySlotNode.cleanup(frame, dispatchObject, slot);
         }
     }
 
@@ -399,21 +398,13 @@ public abstract class RCallNode extends RCallBaseNode implements RSyntaxNode, RS
         RStringVector typeX = classHierarchyNodeX.execute(promiseHelperNode.checkEvaluate(frame, args[typeXIdx]));
         Result resultX = null;
         if (implicitTypeProfileX.profile(typeX != null)) {
-            try {
-                resultX = dispatchLookupX.execute(frame, builtin.getName(), typeX, dispatch.getGroupGenericName(), frame.materialize(), null);
-            } catch (NoGenericMethodException e) {
-                // fall-through
-            }
+            resultX = dispatchLookupX.execute(frame, builtin.getName(), typeX, dispatch.getGroupGenericName(), frame.materialize(), null);
         }
         Result resultY = null;
         if (args.length > 1 && dispatch == RDispatch.OPS_GROUP_GENERIC) {
             RStringVector typeY = classHierarchyNodeY.execute(promiseHelperNode.checkEvaluate(frame, args[1]));
             if (implicitTypeProfileY.profile(typeY != null)) {
-                try {
-                    resultY = dispatchLookupY.execute(frame, builtin.getName(), typeY, dispatch.getGroupGenericName(), frame.materialize(), null);
-                } catch (NoGenericMethodException e) {
-                    // fall-through
-                }
+                resultY = dispatchLookupY.execute(frame, builtin.getName(), typeY, dispatch.getGroupGenericName(), frame.materialize(), null);
             }
         }
 
@@ -548,11 +539,11 @@ public abstract class RCallNode extends RCallBaseNode implements RSyntaxNode, RS
         return getParentCallNode().getFunctionNode();
     }
 
-    public CallArgumentsNode createArguments(Object[] dispatchTempIdentifiers, boolean modeChange, boolean modeChangeAppliesToAll) {
+    public CallArgumentsNode createArguments(FrameSlot tempFrameSlot, boolean modeChange, boolean modeChangeAppliesToAll) {
         RNode[] args = new RNode[arguments.length];
         for (int i = 0; i < arguments.length; i++) {
-            if (dispatchTempIdentifiers != null && i < dispatchTempIdentifiers.length) {
-                args[i] = new GetTempNode(dispatchTempIdentifiers[i], arguments[i]);
+            if (tempFrameSlot != null && i == 0) {
+                args[i] = new GetTempNode(tempFrameSlot, arguments[i]);
             } else {
                 args[i] = arguments[i] == null ? null : RASTUtils.cloneNode(arguments[i].asRNode());
             }
@@ -570,7 +561,7 @@ public abstract class RCallNode extends RCallBaseNode implements RSyntaxNode, RS
      */
     public static RNode createInternalCall(RCallNode internalCallArg, RFunction function) {
         CompilerAsserts.neverPartOfCompilation();
-        return new InternalNode(FunctionDispatchNodeGen.create(internalCallArg, null, false), function, internalCallArg.lookupVarArgs != null);
+        return new InternalNode(FunctionDispatchNodeGen.create(internalCallArg, false, null), function, internalCallArg.lookupVarArgs != null);
     }
 
     @NodeInfo(cost = NodeCost.NONE)
@@ -654,11 +645,11 @@ public abstract class RCallNode extends RCallBaseNode implements RSyntaxNode, RS
 
     private static final class GetTempNode extends RNode {
 
-        @Child private FrameSlotNode slot;
+        private final FrameSlot slot;
         private final RSyntaxNode arg;
 
-        GetTempNode(Object identifier, RSyntaxNode arg) {
-            slot = FrameSlotNode.createTemp(identifier, false);
+        GetTempNode(FrameSlot slot, RSyntaxNode arg) {
+            this.slot = slot;
             this.arg = arg;
         }
 
@@ -670,7 +661,7 @@ public abstract class RCallNode extends RCallBaseNode implements RSyntaxNode, RS
         @Override
         public Object execute(VirtualFrame frame) {
             try {
-                return frame.getObject(slot.executeFrameSlot(frame));
+                return frame.getObject(slot);
             } catch (FrameSlotTypeException e) {
                 throw RInternalError.shouldNotReachHere();
             }
@@ -691,13 +682,14 @@ public abstract class RCallNode extends RCallBaseNode implements RSyntaxNode, RS
         protected static final int CACHE_SIZE = 4;
 
         private final RCallNode originalCall;
-        private final Object[] dispatchTempIdentifiers;
         private final boolean explicitArgs;
 
-        public FunctionDispatch(RCallNode originalCall, Object[] dispatchTempIdentifiers, boolean explicitArgs) {
+        private final FrameSlot tempFrameSlot;
+
+        public FunctionDispatch(RCallNode originalCall, boolean explicitArgs, FrameSlot tempFrameSlot) {
             this.originalCall = originalCall;
-            this.dispatchTempIdentifiers = dispatchTempIdentifiers;
             this.explicitArgs = explicitArgs;
+            this.tempFrameSlot = tempFrameSlot;
         }
 
         protected LeafCallNode createCacheNode(RootCallTarget cachedTarget) {
@@ -717,7 +709,7 @@ public abstract class RCallNode extends RCallBaseNode implements RSyntaxNode, RS
             if (explicitArgs) {
                 return PrepareArguments.createExplicit(root);
             } else {
-                CallArgumentsNode args = originalCall.createArguments(dispatchTempIdentifiers, root.getBuiltin() == null, true);
+                CallArgumentsNode args = originalCall.createArguments(tempFrameSlot, root.getBuiltin() == null, true);
                 return PrepareArguments.create(root, args, noOpt);
             }
         }
diff --git a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/function/RCallSpecialNode.java b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/function/RCallSpecialNode.java
index 2d0f542a9fb23b5a2a72e5f0b640ed9bf290aa6c..f8da9da2c7a6a7aa6910fcd49ccb81ba6b026193 100644
--- a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/function/RCallSpecialNode.java
+++ b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/function/RCallSpecialNode.java
@@ -98,23 +98,23 @@ public final class RCallSpecialNode extends RCallBaseNode implements RSyntaxNode
     private static final boolean useSpecials = FastROptions.UseSpecials.getBooleanValue();
 
     // currently cannot be RSourceSectionNode because of TruffleDSL restrictions
-    @CompilationFinal private SourceSection sourceSectionR;
+    @CompilationFinal private SourceSection sourceSection;
 
     @Override
     public void setSourceSection(SourceSection sourceSection) {
         assert sourceSection != null;
-        this.sourceSectionR = sourceSection;
+        this.sourceSection = sourceSection;
     }
 
     @Override
     public SourceSection getLazySourceSection() {
-        return sourceSectionR;
+        return sourceSection;
     }
 
     @Override
     public SourceSection getSourceSection() {
         RDeparse.ensureSourceSection(this);
-        return sourceSectionR;
+        return sourceSection;
     }
 
     @Child private ForcePromiseNode functionNode;
@@ -136,7 +136,7 @@ public final class RCallSpecialNode extends RCallBaseNode implements RSyntaxNode
     private RCallSpecialNode callSpecialParent;
 
     private RCallSpecialNode(SourceSection sourceSection, RNode functionNode, RFunction expectedFunction, RSyntaxNode[] arguments, ArgumentsSignature signature, RNode special) {
-        this.sourceSectionR = sourceSection;
+        this.sourceSection = sourceSection;
         this.expectedFunction = expectedFunction;
         this.special = special;
         this.functionNode = new ForcePromiseNode(functionNode);
@@ -197,16 +197,17 @@ public final class RCallSpecialNode extends RCallBaseNode implements RSyntaxNode
         }
         RNode[] localArguments = new RNode[arguments.length];
         for (int i = 0; i < arguments.length; i++) {
+            RSyntaxNode arg = arguments[i];
             if (inReplace && contains(ignoredArguments, i)) {
-                localArguments[i] = arguments[i].asRNode();
+                localArguments[i] = arg.asRNode();
             } else {
-                if (arguments[i] instanceof RSyntaxLookup) {
-                    localArguments[i] = new PeekLocalVariableNode(((RSyntaxLookup) arguments[i]).getIdentifier());
-                } else if (arguments[i] instanceof RSyntaxConstant) {
-                    localArguments[i] = RContext.getASTBuilder().process(arguments[i]).asRNode();
+                if (arg instanceof RSyntaxLookup) {
+                    localArguments[i] = new PeekLocalVariableNode(((RSyntaxLookup) arg).getIdentifier());
+                } else if (arg instanceof RSyntaxConstant) {
+                    localArguments[i] = RContext.getASTBuilder().process(arg).asRNode();
                 } else {
-                    assert arguments[i] instanceof RCallSpecialNode;
-                    localArguments[i] = arguments[i].asRNode();
+                    assert arg instanceof RCallSpecialNode;
+                    localArguments[i] = arg.asRNode();
                 }
             }
         }
@@ -271,7 +272,7 @@ public final class RCallSpecialNode extends RCallBaseNode implements RSyntaxNode
     }
 
     private RCallNode getRCallNode(RSyntaxNode[] newArguments) {
-        return RCallNode.createCall(sourceSectionR, functionNode == null ? null : functionNode.getValueNode(), signature, newArguments);
+        return RCallNode.createCall(sourceSection, functionNode == null ? null : functionNode.getValueNode(), signature, newArguments);
     }
 
     private RCallNode getRCallNode() {
diff --git a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/function/S3FunctionLookupNode.java b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/function/S3FunctionLookupNode.java
index 41082f5156c4439809ac6c083d56da246f3f28c3..2ddb5474316dbf7260cda12b317c9002b32fb671 100644
--- a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/function/S3FunctionLookupNode.java
+++ b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/function/S3FunctionLookupNode.java
@@ -23,7 +23,6 @@ import com.oracle.truffle.api.frame.FrameSlot;
 import com.oracle.truffle.api.frame.FrameSlotTypeException;
 import com.oracle.truffle.api.frame.MaterializedFrame;
 import com.oracle.truffle.api.frame.VirtualFrame;
-import com.oracle.truffle.api.nodes.ControlFlowException;
 import com.oracle.truffle.api.nodes.ExplodeLoop;
 import com.oracle.truffle.api.nodes.NodeCost;
 import com.oracle.truffle.api.nodes.NodeInfo;
@@ -33,6 +32,7 @@ import com.oracle.truffle.api.profiles.ValueProfile;
 import com.oracle.truffle.r.nodes.access.variables.LocalReadVariableNode;
 import com.oracle.truffle.r.nodes.access.variables.ReadVariableNode;
 import com.oracle.truffle.r.runtime.ArgumentsSignature;
+import com.oracle.truffle.r.runtime.RArguments.S3Args;
 import com.oracle.truffle.r.runtime.RError;
 import com.oracle.truffle.r.runtime.RInternalError;
 import com.oracle.truffle.r.runtime.RRuntime;
@@ -74,18 +74,22 @@ public abstract class S3FunctionLookupNode extends RBaseNode {
             this.targetFunctionName = targetFunctionName;
             this.groupMatch = groupMatch;
         }
+
+        public S3Args createS3Args(Frame frame) {
+            return new S3Args(generic, clazz, targetFunctionName, frame.materialize(), null, null);
+        }
     }
 
     public static S3FunctionLookupNode create(boolean throwsError, boolean nextMethod) {
-        return new UseMethodFunctionLookupUninitializedNode(throwsError, nextMethod);
+        return new UseMethodFunctionLookupUninitializedNode(throwsError, nextMethod, 0);
     }
 
     public static S3FunctionLookupNode createWithError() {
-        return new UseMethodFunctionLookupUninitializedNode(true, false);
+        return new UseMethodFunctionLookupUninitializedNode(true, false, 0);
     }
 
     public static S3FunctionLookupNode createWithException() {
-        return new UseMethodFunctionLookupUninitializedNode(false, false);
+        return new UseMethodFunctionLookupUninitializedNode(false, false, 0);
     }
 
     @FunctionalInterface
@@ -235,19 +239,21 @@ public abstract class S3FunctionLookupNode extends RBaseNode {
 
     @NodeInfo(cost = NodeCost.UNINITIALIZED)
     private static final class UseMethodFunctionLookupUninitializedNode extends S3FunctionLookupNode {
-        private int depth;
+        private final int depth;
 
-        UseMethodFunctionLookupUninitializedNode(boolean throwsError, boolean nextMethod) {
+        UseMethodFunctionLookupUninitializedNode(boolean throwsError, boolean nextMethod, int depth) {
             super(throwsError, nextMethod);
+            this.depth = depth;
         }
 
         @Override
         public Result execute(VirtualFrame frame, String genericName, RStringVector type, String group, MaterializedFrame callerFrame, MaterializedFrame genericDefFrame) {
             CompilerDirectives.transferToInterpreterAndInvalidate();
-            if (++depth > MAX_CACHE_DEPTH) {
+            if (depth > MAX_CACHE_DEPTH) {
                 return replace(new UseMethodFunctionLookupGenericNode(throwsError, nextMethod)).execute(frame, genericName, type, group, callerFrame, genericDefFrame);
             } else {
-                UseMethodFunctionLookupCachedNode cachedNode = replace(specialize(frame, genericName, type, group, callerFrame, genericDefFrame, this));
+                UseMethodFunctionLookupCachedNode cachedNode = replace(
+                                specialize(frame, genericName, type, group, callerFrame, genericDefFrame, new UseMethodFunctionLookupUninitializedNode(throwsError, nextMethod, depth + 1)));
                 return cachedNode.execute(frame, genericName, type, group, callerFrame, genericDefFrame);
             }
         }
@@ -329,7 +335,7 @@ public abstract class S3FunctionLookupNode extends RBaseNode {
                     }
                     throw RError.error(this, RError.Message.UNKNOWN_FUNCTION_USE_METHOD, genericName, type);
                 } else {
-                    throw S3FunctionLookupNode.NoGenericMethodException.instance;
+                    return null;
                 }
             } while (true);
             CompilerDirectives.transferToInterpreterAndInvalidate();
@@ -431,19 +437,10 @@ public abstract class S3FunctionLookupNode extends RBaseNode {
                     }
                     throw RError.error(this, RError.Message.UNKNOWN_FUNCTION_USE_METHOD, genericName, RRuntime.toString(type));
                 } else {
-                    throw S3FunctionLookupNode.NoGenericMethodException.instance;
+                    return null;
                 }
             }
             return result;
         }
     }
-
-    @SuppressWarnings("serial")
-    public static final class NoGenericMethodException extends ControlFlowException {
-        private static final NoGenericMethodException instance = new NoGenericMethodException();
-
-        private NoGenericMethodException() {
-            // singleton
-        }
-    }
 }
diff --git a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/function/TemporarySlotNode.java b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/function/TemporarySlotNode.java
index cab3f3c4da90b28fb840338a03006ebcd7bb9b31..03e13b0d068b6a277a8511029d130b4bab6ba20b 100644
--- a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/function/TemporarySlotNode.java
+++ b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/function/TemporarySlotNode.java
@@ -37,33 +37,35 @@ public final class TemporarySlotNode extends Node {
 
     @CompilationFinal private FrameSlot tempSlot;
     private int tempIdentifier;
-    private Object identifier;
 
-    public void initialize(VirtualFrame frame, Object value, Runnable invalidate) {
+    public FrameSlot initialize(VirtualFrame frame, Object value) {
         if (tempSlot == null) {
             CompilerDirectives.transferToInterpreterAndInvalidate();
-            tempSlot = frame.getFrameDescriptor().findOrAddFrameSlot(identifier = defaultTempIdentifiers[0], FrameSlotKind.Object);
-            invalidate.run();
+            tempSlot = frame.getFrameDescriptor().findOrAddFrameSlot(defaultTempIdentifiers[0], FrameSlotKind.Object);
         }
+        FrameSlot slot = tempSlot;
         try {
-            if (frame.getObject(tempSlot) != null) {
+            if (frame.getObject(slot) != null) {
                 CompilerDirectives.transferToInterpreterAndInvalidate();
                 // keep the complete loop in the slow path
                 do {
                     tempIdentifier++;
-                    identifier = tempIdentifier < defaultTempIdentifiers.length ? defaultTempIdentifiers[tempIdentifier] : new Object();
-                    tempSlot = frame.getFrameDescriptor().findOrAddFrameSlot(identifier, FrameSlotKind.Object);
-                    invalidate.run();
-                } while (frame.getObject(tempSlot) != null);
+                    Object identifier = tempIdentifier < defaultTempIdentifiers.length ? defaultTempIdentifiers[tempIdentifier] : new Object();
+                    tempSlot = slot = frame.getFrameDescriptor().findOrAddFrameSlot(identifier, FrameSlotKind.Object);
+                    if (frame.getObject(slot) == null) {
+                        break;
+                    }
+                } while (true);
             }
         } catch (FrameSlotTypeException e) {
             CompilerDirectives.transferToInterpreter();
             throw RInternalError.shouldNotReachHere();
         }
-        frame.setObject(tempSlot, value);
+        frame.setObject(slot, value);
+        return slot;
     }
 
-    public void cleanup(VirtualFrame frame, Object object) {
+    public static void cleanup(VirtualFrame frame, Object object, FrameSlot tempSlot) {
         try {
             assert frame.getObject(tempSlot) == object;
         } catch (FrameSlotTypeException e) {
@@ -71,8 +73,4 @@ public final class TemporarySlotNode extends Node {
         }
         frame.setObject(tempSlot, null);
     }
-
-    public Object getIdentifier() {
-        return identifier;
-    }
 }
diff --git a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/function/UseMethodInternalNode.java b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/function/UseMethodInternalNode.java
deleted file mode 100644
index 739931976e6def1f5933a27c1c92806339e413c4..0000000000000000000000000000000000000000
--- a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/function/UseMethodInternalNode.java
+++ /dev/null
@@ -1,58 +0,0 @@
-/*
- * This material is distributed under the GNU General Public License
- * Version 2. You may review the terms of this license at
- * http://www.gnu.org/licenses/gpl-2.0.html
- *
- * Copyright (c) 2014, Purdue University
- * Copyright (c) 2014, 2016, Oracle and/or its affiliates
- *
- * All rights reserved.
- */
-package com.oracle.truffle.r.nodes.function;
-
-import com.oracle.truffle.api.CompilerDirectives;
-import com.oracle.truffle.api.frame.VirtualFrame;
-import com.oracle.truffle.r.nodes.function.S3FunctionLookupNode.Result;
-import com.oracle.truffle.r.runtime.ArgumentsSignature;
-import com.oracle.truffle.r.runtime.FastROptions;
-import com.oracle.truffle.r.runtime.RArguments.S3Args;
-import com.oracle.truffle.r.runtime.RInternalError;
-import com.oracle.truffle.r.runtime.data.RStringVector;
-import com.oracle.truffle.r.runtime.nodes.RNode;
-
-public final class UseMethodInternalNode extends RNode {
-
-    @Child private ClassHierarchyNode classHierarchyNode = ClassHierarchyNodeGen.create(true, true);
-    @Child private S3FunctionLookupNode lookup = S3FunctionLookupNode.create(false, false);
-    @Child private CallMatcherNode callMatcher = CallMatcherNode.create(false);
-    @Child private PreProcessArgumentsNode argPreProcess;
-
-    private final String generic;
-    private final ArgumentsSignature signature;
-    private final boolean wrap;
-
-    public UseMethodInternalNode(String generic, ArgumentsSignature signature, boolean wrap) {
-        this.generic = generic;
-        this.signature = signature;
-        this.wrap = wrap && FastROptions.InvisibleArgs.getBooleanValue();
-    }
-
-    public Object execute(VirtualFrame frame, RStringVector type, Object[] arguments) {
-        Result lookupResult = lookup.execute(frame, generic, type, null, frame.materialize(), null);
-        if (wrap) {
-            assert arguments != null;
-            if (argPreProcess == null || argPreProcess.getLength() != arguments.length) {
-                CompilerDirectives.transferToInterpreterAndInvalidate();
-                argPreProcess = insert(PreProcessArgumentsNode.create(arguments.length));
-            }
-            argPreProcess.execute(frame, arguments);
-        }
-        S3Args s3Args = new S3Args(generic, lookupResult.clazz, lookupResult.targetFunctionName, frame.materialize(), null, null);
-        return callMatcher.execute(frame, signature, arguments, lookupResult.function, lookupResult.targetFunctionName, s3Args);
-    }
-
-    @Override
-    public Object execute(VirtualFrame frame) {
-        throw RInternalError.shouldNotReachHere();
-    }
-}
diff --git a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/function/WrapArgumentNode.java b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/function/WrapArgumentNode.java
index 7ed844a144758904c56d2f9e9463f19e2c1d3673..8a6471d4845ffb956178fdb29cb6fac32f94240a 100644
--- a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/function/WrapArgumentNode.java
+++ b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/function/WrapArgumentNode.java
@@ -25,7 +25,6 @@ package com.oracle.truffle.r.nodes.function;
 import com.oracle.truffle.api.frame.VirtualFrame;
 import com.oracle.truffle.api.nodes.NodeCost;
 import com.oracle.truffle.api.nodes.UnexpectedResultException;
-import com.oracle.truffle.api.profiles.BranchProfile;
 import com.oracle.truffle.r.nodes.access.ConstantNode;
 import com.oracle.truffle.r.runtime.data.RMissing;
 import com.oracle.truffle.r.runtime.data.RNull;
@@ -44,8 +43,6 @@ public final class WrapArgumentNode extends WrapArgumentBaseNode {
 
     @Child private ArgumentStatePush argPushStateNode;
 
-    private final BranchProfile refCounted = BranchProfile.create();
-
     private WrapArgumentNode(RNode operand, boolean modeChange, int index) {
         super(operand, modeChange);
         this.modeChange = modeChange;
@@ -79,9 +76,6 @@ public final class WrapArgumentNode extends WrapArgumentBaseNode {
             if (rShareable != null) {
                 shareable.enter();
                 argPushStateNode.executeObject(frame, rShareable);
-            } else if (argPushStateNode.refCounted()) {
-                refCounted.enter();
-                argPushStateNode.executeObject(frame, RNull.instance);
             }
         }
         return result;
diff --git a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/function/call/PrepareArguments.java b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/function/call/PrepareArguments.java
index 60218f9968d1610f1a04a6f303e88eb16bbd1e53..5b48ec10193c4ede8faf5340e4ed14b5eee1032d 100644
--- a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/function/call/PrepareArguments.java
+++ b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/function/call/PrepareArguments.java
@@ -23,15 +23,23 @@
 package com.oracle.truffle.r.nodes.function.call;
 
 import com.oracle.truffle.api.CompilerDirectives;
+import com.oracle.truffle.api.CompilerDirectives.TruffleBoundary;
+import com.oracle.truffle.api.dsl.Cached;
+import com.oracle.truffle.api.dsl.Fallback;
+import com.oracle.truffle.api.dsl.Specialization;
+import com.oracle.truffle.api.dsl.TypeSystemReference;
 import com.oracle.truffle.api.frame.VirtualFrame;
 import com.oracle.truffle.api.nodes.ExplodeLoop;
 import com.oracle.truffle.api.nodes.Node;
+import com.oracle.truffle.r.nodes.EmptyTypeSystemFlatLayout;
 import com.oracle.truffle.r.nodes.RRootNode;
 import com.oracle.truffle.r.nodes.function.ArgumentMatcher;
 import com.oracle.truffle.r.nodes.function.ArgumentMatcher.MatchPermutation;
 import com.oracle.truffle.r.nodes.function.CallArgumentsNode;
 import com.oracle.truffle.r.nodes.function.FormalArguments;
 import com.oracle.truffle.r.nodes.function.RCallNode;
+import com.oracle.truffle.r.nodes.function.call.PrepareArgumentsFactory.PrepareArgumentsDefaultNodeGen;
+import com.oracle.truffle.r.nodes.function.call.PrepareArgumentsFactory.PrepareArgumentsExplicitNodeGen;
 import com.oracle.truffle.r.runtime.Arguments;
 import com.oracle.truffle.r.runtime.ArgumentsSignature;
 import com.oracle.truffle.r.runtime.RArguments.S3DefaultArguments;
@@ -44,171 +52,111 @@ import com.oracle.truffle.r.runtime.nodes.RNode;
  * rules. It implements two different paths: one for arguments provided as an
  * {@link CallArgumentsNode}, i.e., unevaluated arguments, and another path for evaluated arguments.
  */
+@TypeSystemReference(EmptyTypeSystemFlatLayout.class)
 public abstract class PrepareArguments extends Node {
 
-    private static final int CACHE_SIZE = 4;
+    protected static final int CACHE_SIZE = 8;
 
-    /**
-     * Returns the argument values and corresponding signature. The signature represents the
-     * original call signature reordered in the same way as the arguments. For s3DefaultArguments
-     * motivation see {@link RCallNode#callGroupGeneric}.
-     */
-    public abstract RArgsValuesAndNames execute(VirtualFrame frame, RArgsValuesAndNames varArgs, S3DefaultArguments s3DefaultArguments, RCallNode call);
+    abstract static class PrepareArgumentsDefault extends PrepareArguments {
 
-    public static PrepareArguments create(RRootNode target, CallArgumentsNode args, boolean noOpt) {
-        return new UninitializedPrepareArguments(target, args, noOpt);
-    }
+        protected final RRootNode target;
+        protected final CallArgumentsNode sourceArguments; // not used as a node
+        protected final boolean noOpt;
 
-    public static PrepareArguments createExplicit(RRootNode target) {
-        return new UninitializedExplicitPrepareArguments(target);
-    }
+        static final class ArgumentsAndSignature extends Node {
+            @Children private final RNode[] matchedArguments;
+            private final ArgumentsSignature matchedSuppliedSignature;
 
-    @ExplodeLoop
-    private static RArgsValuesAndNames executeArgs(RNode[] arguments, ArgumentsSignature suppliedSignature, VirtualFrame frame) {
-        Object[] result = new Object[arguments.length];
-        for (int i = 0; i < arguments.length; i++) {
-            result[i] = arguments[i].execute(frame);
+            protected ArgumentsAndSignature(RNode[] matchedArguments, ArgumentsSignature matchedSuppliedSignature) {
+                this.matchedArguments = matchedArguments;
+                this.matchedSuppliedSignature = matchedSuppliedSignature;
+            }
         }
-        return new RArgsValuesAndNames(result, suppliedSignature);
-    }
-
-    private static RArgsValuesAndNames executeArgs(Arguments<RNode> matched, VirtualFrame frame) {
-        return executeArgs(matched.getArguments(), matched.getSignature(), frame);
-    }
-
-    private static final class UninitializedPrepareArguments extends PrepareArguments {
 
-        private final RRootNode target;
-        private final CallArgumentsNode sourceArguments; // not used as a node
-        private final boolean noOpt;
-        private int depth = CACHE_SIZE;
+        protected static ArgumentsSignature getSignatureOrNull(RArgsValuesAndNames args) {
+            return args == null ? null : args.getSignature();
+        }
 
-        UninitializedPrepareArguments(RRootNode target, CallArgumentsNode sourceArguments, boolean noOpt) {
+        protected PrepareArgumentsDefault(RRootNode target, CallArgumentsNode sourceArguments, boolean noOpt) {
             this.target = target;
             this.sourceArguments = sourceArguments;
             this.noOpt = noOpt;
         }
 
-        @Override
-        public RArgsValuesAndNames execute(VirtualFrame frame, RArgsValuesAndNames varArgs, S3DefaultArguments s3DefaultArguments, RCallNode call) {
-            CompilerDirectives.transferToInterpreterAndInvalidate();
-            PrepareArguments next;
-            if (depth-- > 0) {
-                next = new CachedPrepareArguments(this, target, call, sourceArguments, varArgs == null ? null : varArgs.getSignature(), s3DefaultArguments, noOpt);
-            } else {
-                next = new GenericPrepareArguments(target, sourceArguments);
-            }
-            return replace(next).execute(frame, varArgs, s3DefaultArguments, call);
-        }
-    }
-
-    private static final class CachedPrepareArguments extends PrepareArguments {
-
-        @Child private PrepareArguments next;
-        @Children private final RNode[] matchedArguments;
-        private final ArgumentsSignature matchedSuppliedSignature;
-        private final ArgumentsSignature cachedVarArgSignature;
-        private final Object cachedS3DefaultArguments;
-
-        CachedPrepareArguments(PrepareArguments next, RRootNode target, RCallNode call, CallArgumentsNode args, ArgumentsSignature varArgSignature, S3DefaultArguments s3DefaultArguments,
-                        boolean noOpt) {
-            this.next = next;
-            cachedVarArgSignature = varArgSignature;
-            Arguments<RNode> matched = ArgumentMatcher.matchArguments(target, args, varArgSignature, s3DefaultArguments, call, noOpt);
-            this.matchedArguments = matched.getArguments();
-            this.matchedSuppliedSignature = matched.getSignature();
-            this.cachedS3DefaultArguments = s3DefaultArguments;
+        protected ArgumentsAndSignature createArguments(RCallNode call, ArgumentsSignature varArgSignature, S3DefaultArguments s3DefaultArguments) {
+            Arguments<RNode> matched = ArgumentMatcher.matchArguments(target, sourceArguments, varArgSignature, s3DefaultArguments, call, noOpt);
+            return new ArgumentsAndSignature(matched.getArguments(), matched.getSignature());
         }
 
-        @Override
         @ExplodeLoop
-        public RArgsValuesAndNames execute(VirtualFrame frame, RArgsValuesAndNames varArgs, S3DefaultArguments s3DefaultArguments, RCallNode call) {
-            assert (cachedVarArgSignature != null) == (varArgs != null);
-            if ((cachedVarArgSignature == null || cachedVarArgSignature == varArgs.getSignature()) && cachedS3DefaultArguments == s3DefaultArguments) {
-                return executeArgs(matchedArguments, matchedSuppliedSignature, frame);
+        private static RArgsValuesAndNames executeArgs(RNode[] arguments, ArgumentsSignature suppliedSignature, VirtualFrame frame) {
+            Object[] result = new Object[arguments.length];
+            for (int i = 0; i < arguments.length; i++) {
+                result[i] = arguments[i].execute(frame);
             }
-            return next.execute(frame, varArgs, s3DefaultArguments, call);
+            return new RArgsValuesAndNames(result, suppliedSignature);
         }
-    }
-
-    private static final class GenericPrepareArguments extends PrepareArguments {
 
-        private final RRootNode target;
-        private final CallArgumentsNode args; // not used as a node
-
-        GenericPrepareArguments(RRootNode target, CallArgumentsNode args) {
-            this.target = target;
-            this.args = args;
+        @Specialization(limit = "CACHE_SIZE", guards = {"cachedVarArgSignature == null || cachedVarArgSignature == varArgs.getSignature()", "cachedS3DefaultArguments == s3DefaultArguments"})
+        public RArgsValuesAndNames prepare(VirtualFrame frame, RArgsValuesAndNames varArgs, @SuppressWarnings("unused") S3DefaultArguments s3DefaultArguments,
+                        @SuppressWarnings("unused") RCallNode call,
+                        @Cached("getSignatureOrNull(varArgs)") ArgumentsSignature cachedVarArgSignature,
+                        @Cached("createArguments(call, cachedVarArgSignature, s3DefaultArguments)") ArgumentsAndSignature arguments,
+                        @SuppressWarnings("unused") @Cached("s3DefaultArguments") S3DefaultArguments cachedS3DefaultArguments) {
+            assert (cachedVarArgSignature != null) == (varArgs != null);
+            return executeArgs(arguments.matchedArguments, arguments.matchedSuppliedSignature, frame);
         }
 
-        @Override
-        public RArgsValuesAndNames execute(VirtualFrame frame, RArgsValuesAndNames varArgs, S3DefaultArguments s3DefaultArguments, RCallNode call) {
+        @Fallback
+        public RArgsValuesAndNames prepareGeneric(VirtualFrame frame, RArgsValuesAndNames varArgs, S3DefaultArguments s3DefaultArguments, @SuppressWarnings("unused") RCallNode call) {
             CompilerDirectives.transferToInterpreter();
             ArgumentsSignature varArgSignature = varArgs == null ? null : varArgs.getSignature();
-            Arguments<RNode> matchedArgs = ArgumentMatcher.matchArguments(target, args, varArgSignature, s3DefaultArguments, RError.ROOTNODE, true);
-            return executeArgs(matchedArgs, frame);
+            Arguments<RNode> matchedArgs = ArgumentMatcher.matchArguments(target, sourceArguments, varArgSignature, s3DefaultArguments, RError.ROOTNODE, true);
+            return executeArgs(matchedArgs.getArguments(), matchedArgs.getSignature(), frame);
         }
     }
 
-    private static final class UninitializedExplicitPrepareArguments extends PrepareArguments {
+    abstract static class PrepareArgumentsExplicit extends PrepareArguments {
 
-        private final RRootNode target;
-        private int depth = CACHE_SIZE;
+        protected final RRootNode target;
+        private final FormalArguments formals;
 
-        UninitializedExplicitPrepareArguments(RRootNode target) {
+        protected PrepareArgumentsExplicit(RRootNode target) {
             this.target = target;
+            this.formals = target.getFormalArguments();
         }
 
-        @Override
-        public RArgsValuesAndNames execute(VirtualFrame frame, RArgsValuesAndNames explicitArgs, S3DefaultArguments s3DefaultArguments, RCallNode call) {
-            CompilerDirectives.transferToInterpreterAndInvalidate();
-            PrepareArguments next;
-            if (depth-- > 0) {
-                next = new CachedExplicitPrepareArguments(this, target, call, explicitArgs == null ? null : explicitArgs.getSignature());
-            } else {
-                next = new GenericExplicitPrepareArguments(target);
-            }
-            return replace(next).execute(frame, explicitArgs, s3DefaultArguments, call);
+        protected MatchPermutation createArguments(RCallNode call, ArgumentsSignature explicitArgSignature) {
+            return ArgumentMatcher.matchArguments(explicitArgSignature, formals.getSignature(), call, target.getBuiltin());
         }
-    }
-
-    private static final class CachedExplicitPrepareArguments extends PrepareArguments {
-
-        @Child private PrepareArguments next;
-
-        private final MatchPermutation permutation;
-        private final ArgumentsSignature cachedExplicitArgSignature;
-        private final FormalArguments formals;
 
-        CachedExplicitPrepareArguments(PrepareArguments next, RRootNode target, RCallNode call, ArgumentsSignature explicitArgSignature) {
-            this.next = next;
-            formals = target.getFormalArguments();
-            permutation = ArgumentMatcher.matchArguments(explicitArgSignature, formals.getSignature(), call, target.getBuiltin());
-            cachedExplicitArgSignature = explicitArgSignature;
+        @Specialization(limit = "CACHE_SIZE", guards = {"cachedExplicitArgSignature == explicitArgs.getSignature()"})
+        public RArgsValuesAndNames prepare(RArgsValuesAndNames explicitArgs, S3DefaultArguments s3DefaultArguments, @SuppressWarnings("unused") RCallNode call,
+                        @SuppressWarnings("unused") @Cached("explicitArgs.getSignature()") ArgumentsSignature cachedExplicitArgSignature,
+                        @Cached("createArguments(call, cachedExplicitArgSignature)") MatchPermutation permutation) {
+            return ArgumentMatcher.matchArgumentsEvaluated(permutation, explicitArgs.getArguments(), s3DefaultArguments, formals);
         }
 
-        @Override
-        public RArgsValuesAndNames execute(VirtualFrame frame, RArgsValuesAndNames explicitArgs, S3DefaultArguments s3DefaultArguments, RCallNode call) {
-            if (cachedExplicitArgSignature == explicitArgs.getSignature()) {
-                return ArgumentMatcher.matchArgumentsEvaluated(permutation, explicitArgs.getArguments(), s3DefaultArguments, formals);
-            }
-            return next.execute(frame, explicitArgs, s3DefaultArguments, call);
+        @Fallback
+        @TruffleBoundary
+        public RArgsValuesAndNames prepareGeneric(RArgsValuesAndNames explicitArgs, S3DefaultArguments s3DefaultArguments, @SuppressWarnings("unused") RCallNode call) {
+            // Function and arguments may change every call: Flatt'n'Match on SlowPath! :-/
+            return ArgumentMatcher.matchArgumentsEvaluated(target, explicitArgs, s3DefaultArguments, RError.ROOTNODE);
         }
     }
 
-    private static final class GenericExplicitPrepareArguments extends PrepareArguments {
-
-        private final RRootNode target;
+    /**
+     * Returns the argument values and corresponding signature. The signature represents the
+     * original call signature reordered in the same way as the arguments. For s3DefaultArguments
+     * motivation see {@link RCallNode#callGroupGeneric}.
+     */
+    public abstract RArgsValuesAndNames execute(VirtualFrame frame, RArgsValuesAndNames varArgs, S3DefaultArguments s3DefaultArguments, RCallNode call);
 
-        GenericExplicitPrepareArguments(RRootNode target) {
-            this.target = target;
-        }
+    public static PrepareArguments create(RRootNode target, CallArgumentsNode args, boolean noOpt) {
+        return PrepareArgumentsDefaultNodeGen.create(target, args, noOpt);
+    }
 
-        @Override
-        public RArgsValuesAndNames execute(VirtualFrame frame, RArgsValuesAndNames explicitArgs, S3DefaultArguments s3DefaultArguments, RCallNode call) {
-            CompilerDirectives.transferToInterpreter();
-            // Function and arguments may change every call: Flatt'n'Match on SlowPath! :-/
-            return ArgumentMatcher.matchArgumentsEvaluated(target, explicitArgs, s3DefaultArguments, RError.ROOTNODE);
-        }
+    public static PrepareArguments createExplicit(RRootNode target) {
+        return PrepareArgumentsExplicitNodeGen.create(target);
     }
 }
diff --git a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/function/opt/ShareObjectNode.java b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/function/opt/ShareObjectNode.java
index de2c9eda806469d95e22a5c8c9962e4cafe612a0..81ac78c1819f2a472380e7e554f8a6eb87eae8db 100644
--- a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/function/opt/ShareObjectNode.java
+++ b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/function/opt/ShareObjectNode.java
@@ -30,8 +30,10 @@ import com.oracle.truffle.api.dsl.TypeSystemReference;
 import com.oracle.truffle.api.nodes.Node;
 import com.oracle.truffle.api.nodes.NodeInfo;
 import com.oracle.truffle.api.profiles.ConditionProfile;
+import com.oracle.truffle.api.profiles.ValueProfile;
 import com.oracle.truffle.r.nodes.EmptyTypeSystemFlatLayout;
 import com.oracle.truffle.r.runtime.data.RShareable;
+import com.oracle.truffle.r.runtime.data.RSharingAttributeStorage;
 
 /**
  * Internal node that should be used whenever you need to increment reference count of some object.
@@ -48,7 +50,7 @@ public abstract class ShareObjectNode extends Node {
     }
 
     @Specialization
-    protected Object doShareable(RShareable obj,
+    protected Object doShareable(RSharingAttributeStorage obj,
                     @Cached("createBinaryProfile()") ConditionProfile sharedPermanent) {
         if (sharedPermanent.profile(!obj.isSharedPermanent())) {
             obj.incRefCount();
@@ -56,6 +58,17 @@ public abstract class ShareObjectNode extends Node {
         return obj;
     }
 
+    @Specialization
+    protected Object doShareable(RShareable obj,
+                    @Cached("createBinaryProfile()") ConditionProfile sharedPermanent,
+                    @Cached("createClassProfile()") ValueProfile typeProfile) {
+        RShareable objProfiled = typeProfile.profile(obj);
+        if (sharedPermanent.profile(!objProfiled.isSharedPermanent())) {
+            objProfiled.incRefCount();
+        }
+        return obj;
+    }
+
     @Specialization(guards = "!isRShareable(obj)")
     protected Object doNonShareable(Object obj) {
         return obj;
diff --git a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/attributes/UpdateSharedAttributeNode.java b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/function/opt/UpdateShareableChildValueNode.java
similarity index 64%
rename from com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/attributes/UpdateSharedAttributeNode.java
rename to com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/function/opt/UpdateShareableChildValueNode.java
index 58bbb082347854e069fd6c8b633021fabf357dc5..5a5a903247df6a7bc4e65da814296a21479f43e4 100644
--- a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/attributes/UpdateSharedAttributeNode.java
+++ b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/function/opt/UpdateShareableChildValueNode.java
@@ -20,18 +20,19 @@
  * or visit www.oracle.com if you need additional information or have any
  * questions.
  */
-package com.oracle.truffle.r.nodes.attributes;
+package com.oracle.truffle.r.nodes.function.opt;
 
 import com.oracle.truffle.api.dsl.Cached;
 import com.oracle.truffle.api.dsl.Specialization;
 import com.oracle.truffle.api.profiles.ConditionProfile;
 import com.oracle.truffle.api.profiles.ValueProfile;
 import com.oracle.truffle.r.runtime.data.RShareable;
+import com.oracle.truffle.r.runtime.data.RSharingAttributeStorage;
 import com.oracle.truffle.r.runtime.nodes.RBaseNode;
 
-public abstract class UpdateSharedAttributeNode extends RBaseNode {
+public abstract class UpdateShareableChildValueNode extends RBaseNode {
 
-    protected UpdateSharedAttributeNode() {
+    protected UpdateShareableChildValueNode() {
     }
 
     public abstract void execute(Object owner, Object attrValue);
@@ -41,13 +42,15 @@ public abstract class UpdateSharedAttributeNode extends RBaseNode {
         return item;
     }
 
-    public static UpdateSharedAttributeNode create() {
-        return UpdateSharedAttributeNodeGen.create();
+    public static UpdateShareableChildValueNode create() {
+        return UpdateShareableChildValueNodeGen.create();
     }
 
     @Specialization
     protected void doShareableValues(RShareable owner, RShareable value,
                     @Cached("createClassProfile()") ValueProfile valueProfile,
+                    @Cached("createBinaryProfile()") ConditionProfile sharingAttrsStorageOwner,
+                    @Cached("createClassProfile()") ValueProfile ownerProfile,
                     @Cached("createBinaryProfile()") ConditionProfile sharedValue,
                     @Cached("createBinaryProfile()") ConditionProfile temporaryOwner) {
         RShareable profiledValue = valueProfile.profile(value);
@@ -56,17 +59,34 @@ public abstract class UpdateSharedAttributeNode extends RBaseNode {
             return;
         }
 
+        if (sharingAttrsStorageOwner.profile(owner instanceof RSharingAttributeStorage)) {
+            // monomorphic invocations of the owner
+            RSharingAttributeStorage shOwner = (RSharingAttributeStorage) owner;
+            incRef(shOwner, profiledValue, temporaryOwner);
+        } else {
+            // invoking a type-profiled owner
+            RShareable ownerProfiled = ownerProfile.profile(owner);
+            incRef(ownerProfiled, profiledValue, temporaryOwner);
+        }
+    }
+
+    private static void incRef(RShareable owner, RShareable value, ConditionProfile temporaryOwner) {
         if (temporaryOwner.profile(owner.isTemporary())) {
+            // This can happen, for example, when we immediately extract out of a temporary
+            // list that was returned by a built-in, like: strsplit(...)[[1L]]. We do not need
+            // to transition the element, it may stay temporary.
             return;
         }
 
-        if (profiledValue.isTemporary()) {
+        // the owner is at least non-shared
+
+        if (value.isTemporary()) {
             // make it at least non-shared (the owner must be also at least non-shared)
-            profiledValue.incRefCount();
+            value.incRefCount();
         }
         if (owner.isShared()) {
             // owner is shared, make the attribute value shared too
-            profiledValue.incRefCount();
+            value.incRefCount();
         }
     }
 
diff --git a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/function/visibility/SetVisibilityNode.java b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/function/visibility/SetVisibilityNode.java
index c4946fcc9e09c23827fa6b4c357ee1f852024382..e5315d7410c862e2c6038a5a747fcf663aab322c 100644
--- a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/function/visibility/SetVisibilityNode.java
+++ b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/function/visibility/SetVisibilityNode.java
@@ -22,6 +22,7 @@
  */
 package com.oracle.truffle.r.nodes.function.visibility;
 
+import com.oracle.truffle.api.CompilerAsserts;
 import com.oracle.truffle.api.CompilerDirectives;
 import com.oracle.truffle.api.CompilerDirectives.CompilationFinal;
 import com.oracle.truffle.api.frame.Frame;
@@ -32,6 +33,7 @@ import com.oracle.truffle.api.frame.VirtualFrame;
 import com.oracle.truffle.api.nodes.Node;
 import com.oracle.truffle.api.nodes.NodeCost;
 import com.oracle.truffle.api.nodes.NodeInfo;
+import com.oracle.truffle.api.nodes.RootNode;
 import com.oracle.truffle.r.runtime.RArguments;
 import com.oracle.truffle.r.runtime.RCaller;
 import com.oracle.truffle.r.runtime.RInternalError;
@@ -86,12 +88,19 @@ public final class SetVisibilityNode extends Node {
      * Needs to be called at the end of each function, so that the visibility is transferred from
      * the current frame into the {@link RCaller}.
      */
-    public void executeEndOfFunction(VirtualFrame frame) {
+    public void executeEndOfFunction(VirtualFrame frame, RootNode root) {
         ensureFrameSlot(frame);
         try {
-            Object visibility = frame.getBoolean(frameSlot);
-            if (visibility != null) {
-                RArguments.getCall(frame).setVisibility(visibility == Boolean.TRUE);
+            if (frame.isBoolean(frameSlot)) {
+                RArguments.getCall(frame).setVisibility(frame.getBoolean(frameSlot) == Boolean.TRUE);
+            } else {
+                CompilerDirectives.transferToInterpreter();
+                /*
+                 * Most likely the (only) builtin call in the function was configured to
+                 * RVisibility.CUSTOM and didn't actually set the visibility. Another possible
+                 * problem is a node that is created by RASTBuilder that does not set visibility.
+                 */
+                throw RInternalError.shouldNotReachHere("visibility not set at the end of " + root.getName());
             }
         } catch (FrameSlotTypeException e) {
             throw RInternalError.shouldNotReachHere(e);
@@ -102,6 +111,7 @@ public final class SetVisibilityNode extends Node {
      * Slow-path version of {@link #executeAfterCall(VirtualFrame, RCaller)}.
      */
     public static void executeAfterCallSlowPath(Frame frame, RCaller caller) {
+        CompilerAsserts.neverPartOfCompilation();
         frame.setBoolean(frame.getFrameDescriptor().findOrAddFrameSlot(RFrameSlot.Visibility, FrameSlotKind.Boolean), caller.getVisibility());
     }
 }
diff --git a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/qirinterface/QIRInterface.java b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/qirinterface/QIRInterface.java
index 18cb4bec10d3fd779241ec53b0987047d9e5ada6..8011336fce314a997c0d394633a4c7c3a4df479b 100644
--- a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/qirinterface/QIRInterface.java
+++ b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/qirinterface/QIRInterface.java
@@ -237,6 +237,7 @@ public final class QIRInterface {
                 case "new.env":
                     return new QIRLambda(null, "new.env", new QIRVariable(null, "_", null), QIRTnil.getInstance());
                 case "return":
+                case "(":
                     final QIRVariable x = new QIRVariable(null, "x", null);
                     return new QIRLambda(null, "identity", x, x);
                 default:
diff --git a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/unary/CastListNode.java b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/unary/CastListNode.java
index 14ea322f9f4f9e49447990349ea395b987d9f135..606b54d966886466339e13999070d035d9622b8c 100644
--- a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/unary/CastListNode.java
+++ b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/unary/CastListNode.java
@@ -101,8 +101,8 @@ public abstract class CastListNode extends CastBaseNode {
                 if (attr.getName().equals(RRuntime.CLASS_ATTR_KEY)) {
 
                     if (setClassAttrNode == null) {
-                        setClassAttrNode = insert(SetClassAttributeNode.create());
                         CompilerDirectives.transferToInterpreterAndInvalidate();
+                        setClassAttrNode = insert(SetClassAttributeNode.create());
                     }
 
                     setClassAttrNode.execute(result, attr.getValue());
diff --git a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/unary/FirstBooleanNode.java b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/unary/FirstBooleanNode.java
index 969af883b5f41bfc44117671d807b1dab9d0d91e..6a9e9306fce88892407eada830dfde694a26588e 100644
--- a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/unary/FirstBooleanNode.java
+++ b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/unary/FirstBooleanNode.java
@@ -58,7 +58,7 @@ public abstract class FirstBooleanNode extends CastNode {
     protected boolean firstScalar(byte argument) {
         if (RRuntime.isNA(argument)) {
             CompilerDirectives.transferToInterpreter();
-            RError.error(this, invalidValueName == null ? Message.NA_UNEXP : Message.INVALID_VALUE, invalidValueName);
+            throw RError.error(this, invalidValueName == null ? Message.NA_UNEXP : Message.INVALID_VALUE, invalidValueName);
         }
         return RRuntime.fromLogical(argument);
     }
diff --git a/com.oracle.truffle.r.runtime.ffi/src/com/oracle/truffle/r/runtime/ffi/JavaUpCallsRFFI.java b/com.oracle.truffle.r.runtime.ffi/src/com/oracle/truffle/r/runtime/ffi/JavaUpCallsRFFI.java
index d51986b5013153204a5c9b511534bd21d37f4de5..77b7024330594169c34bfebe20c65f3ceaddf35f 100644
--- a/com.oracle.truffle.r.runtime.ffi/src/com/oracle/truffle/r/runtime/ffi/JavaUpCallsRFFI.java
+++ b/com.oracle.truffle.r.runtime.ffi/src/com/oracle/truffle/r/runtime/ffi/JavaUpCallsRFFI.java
@@ -135,7 +135,7 @@ public class JavaUpCallsRFFI implements UpCallsRFFI {
         }
     }
 
-    private static <T> T guaranteeInstanceOf(Object x, Class<T> clazz) {
+    public static <T> T guaranteeInstanceOf(Object x, Class<T> clazz) {
         if (x == null) {
             guarantee(false, "unexpected type: null instead of " + clazz.getSimpleName());
         } else if (!clazz.isInstance(x)) {
@@ -388,7 +388,7 @@ public class JavaUpCallsRFFI implements UpCallsRFFI {
         }
     }
 
-    private static RStringVector getClassHr(Object v) {
+    public static RStringVector getClassHr(Object v) {
         RStringVector result;
         if (v instanceof RAttributable) {
             result = ((RAttributable) v).getClassHierarchy();
diff --git a/com.oracle.truffle.r.runtime.ffi/src/com/oracle/truffle/r/runtime/ffi/Load_RFFIFactory.java b/com.oracle.truffle.r.runtime.ffi/src/com/oracle/truffle/r/runtime/ffi/Load_RFFIFactory.java
index 003cfc0e03d5cd67a3e6fde4468a32f33eed1fb3..5450aec0a2854787bd2fcd81ca70db4366e1c6fd 100644
--- a/com.oracle.truffle.r.runtime.ffi/src/com/oracle/truffle/r/runtime/ffi/Load_RFFIFactory.java
+++ b/com.oracle.truffle.r.runtime.ffi/src/com/oracle/truffle/r/runtime/ffi/Load_RFFIFactory.java
@@ -26,18 +26,11 @@ import com.oracle.truffle.r.runtime.Utils;
 
 /**
  * Selects a particular subclass of {@link RFFIFactory}. Specification is based on system property
- * {@value #FACTORY_CLASS_PROPERTY}. Current default is a JNR-based implementation.
+ * {@value #FACTORY_CLASS_PROPERTY}. Current default is a JNI-based implementation.
  */
 public class Load_RFFIFactory {
     private static final String FACTORY_CLASS_PROPERTY = "fastr.ffi.factory.class";
-    private static final String PACKAGE_PREFIX = "com.oracle.truffle.r.runtime.ffi.";
-    private static final String SUFFIX = "_RFFIFactory";
-    private static final String DEFAULT_FACTORY = "jni";
-    private static final String DEFAULT_FACTORY_CLASS = mapSimpleName(DEFAULT_FACTORY);
-
-    private static String mapSimpleName(String simpleName) {
-        return PACKAGE_PREFIX + simpleName + "." + simpleName.toUpperCase() + SUFFIX;
-    }
+    private static final String DEFAULT_FACTORY_CLASS = "com.oracle.truffle.r.runtime.ffi.jni.JNI_RFFIFactory";
 
     /**
      * Singleton instance of the factory. Typically initialized at runtime but may be initialized
@@ -49,12 +42,7 @@ public class Load_RFFIFactory {
         if (instance == null) {
             String prop = System.getProperty(FACTORY_CLASS_PROPERTY);
             try {
-                if (prop != null) {
-                    if (!prop.contains(".")) {
-                        // simple name
-                        prop = mapSimpleName(prop);
-                    }
-                } else {
+                if (prop == null) {
                     prop = DEFAULT_FACTORY_CLASS;
                 }
                 instance = (RFFIFactory) Class.forName(prop).newInstance();
diff --git a/com.oracle.truffle.r.runtime.ffi/src/com/oracle/truffle/r/runtime/ffi/jni/JNI_Base.java b/com.oracle.truffle.r.runtime.ffi/src/com/oracle/truffle/r/runtime/ffi/jni/JNI_Base.java
index 6aa96a30f9ac2243f21b6d0c463a8a0237fff7ad..08c7928e005e53460b1df305a80ac1336a90e747 100644
--- a/com.oracle.truffle.r.runtime.ffi/src/com/oracle/truffle/r/runtime/ffi/jni/JNI_Base.java
+++ b/com.oracle.truffle.r.runtime.ffi/src/com/oracle/truffle/r/runtime/ffi/jni/JNI_Base.java
@@ -139,13 +139,4 @@ public class JNI_Base implements BaseRFFI {
     private static native long native_strtol(String s, int base, int[] errno);
 
     private static native String native_readlink(String s, int[] errno);
-
-    private static native long native_dlopen(String path, boolean local, boolean now);
-
-    private static native int native_dlclose(long handle);
-
-    private static native String native_dlerror();
-
-    private static native long native_dlsym(long handle, String symbol);
-
 }
diff --git a/com.oracle.truffle.r.runtime.ffi/src/com/oracle/truffle/r/runtime/ffi/jni/JNI_C.java b/com.oracle.truffle.r.runtime.ffi/src/com/oracle/truffle/r/runtime/ffi/jni/JNI_C.java
index 2e7a4c3d7aef66bdb52e71eaafcc12f347d7858e..8ea8d72d97fd793667d4d0ea8831cb275a74c804 100644
--- a/com.oracle.truffle.r.runtime.ffi/src/com/oracle/truffle/r/runtime/ffi/jni/JNI_C.java
+++ b/com.oracle.truffle.r.runtime.ffi/src/com/oracle/truffle/r/runtime/ffi/jni/JNI_C.java
@@ -30,7 +30,7 @@ import com.oracle.truffle.r.runtime.ffi.CRFFI;
 import com.oracle.truffle.r.runtime.ffi.NativeCallInfo;
 
 public class JNI_C implements CRFFI {
-    private static class JNI_CRFFINode extends CRFFINode {
+    public static class JNI_CRFFINode extends CRFFINode {
         /**
          * This is rather similar to {@link JNI_Call}, except the objects are guaranteed to be
          * native array types, no upcalls are possible, and no result is returned. However, the
diff --git a/com.oracle.truffle.r.runtime.ffi/src/com/oracle/truffle/r/runtime/ffi/truffle/LLVM_IR.java b/com.oracle.truffle.r.runtime.ffi/src/com/oracle/truffle/r/runtime/ffi/truffle/LLVM_IR.java
new file mode 100644
index 0000000000000000000000000000000000000000..804ccd512c35c5bd479666a18a381b25a47a94fb
--- /dev/null
+++ b/com.oracle.truffle.r.runtime.ffi/src/com/oracle/truffle/r/runtime/ffi/truffle/LLVM_IR.java
@@ -0,0 +1,97 @@
+/*
+ * Copyright (c) 2016, 2016, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package com.oracle.truffle.r.runtime.ffi.truffle;
+
+import java.io.IOException;
+import java.util.Base64;
+
+import com.oracle.truffle.r.runtime.RInternalError;
+
+public abstract class LLVM_IR {
+    public static final int TEXT_CODE = 1;
+    public static final int BINARY_CODE = 2;
+
+    /**
+     * The name of the "module", aka object file, that the IR pertains to.
+     */
+    public final String name;
+    /**
+     * List of exported symbols.
+     */
+    public final String[] exports;
+    /**
+     * List of imported symbols.
+     */
+    public final String[] imports;
+
+    protected LLVM_IR(String name, String[] exports, String[] imports) {
+        this.name = name;
+        this.exports = exports;
+        this.imports = imports;
+    }
+
+    @Override
+    public String toString() {
+        return name;
+    }
+
+    /**
+     * Denotes textual LLVM IR.
+     */
+    public static final class Text extends LLVM_IR {
+        public final String text;
+
+        public Text(String name, String text, String[] exports, String[] imports) {
+            super(name, exports, imports);
+            this.text = text;
+        }
+    }
+
+    /**
+     * Denotes binary LLVM IR.
+     */
+    public static final class Binary extends LLVM_IR {
+        public final byte[] binary;
+        public final String base64;
+
+        public Binary(String name, byte[] binary, String[] exports, String[] imports) {
+            super(name, exports, imports);
+            this.binary = binary;
+            base64 = Base64.getEncoder().encodeToString(binary);
+        }
+    }
+
+    /**
+     * Return an array of {@link LLVM_IR} instances contained in the library denoted by {@code path}
+     * .
+     */
+    public static LLVM_IR[] getLLVMIR(String path) throws IOException {
+        String os = System.getProperty("os.name");
+        if (os.contains("Mac OS")) {
+            return MachOAccess.getLLVMIR(path);
+        } else {
+            throw RInternalError.unimplemented("LLVM_IR_Access for Linux");
+        }
+    }
+
+}
diff --git a/com.oracle.truffle.r.runtime.ffi/src/com/oracle/truffle/r/runtime/ffi/truffle/MachOAccess.java b/com.oracle.truffle.r.runtime.ffi/src/com/oracle/truffle/r/runtime/ffi/truffle/MachOAccess.java
new file mode 100644
index 0000000000000000000000000000000000000000..af939db7b3115319e7cd3be01c965092692e24e4
--- /dev/null
+++ b/com.oracle.truffle.r.runtime.ffi/src/com/oracle/truffle/r/runtime/ffi/truffle/MachOAccess.java
@@ -0,0 +1,455 @@
+/*
+ * Copyright (c) 2016, 2016, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package com.oracle.truffle.r.runtime.ffi.truffle;
+
+import java.io.*;
+import java.nio.*;
+import java.nio.file.FileSystems;
+import java.nio.file.Files;
+import java.util.ArrayList;
+
+import com.oracle.truffle.r.runtime.RInternalError;
+
+/**
+ * (Limited) Access to Mach_O 64-bit format files. See /usr/include/mach-o/*.h for source. Note that
+ * a file may (unusually) contain multiple binaries for different architectures, see
+ * /usr/include/mach-o/fat.h. Such a file is called a universal binary file, (cf an archive file).
+ *
+ */
+@SuppressWarnings("unused")
+final class MachOAccess implements AutoCloseable {
+    private final RandomAccessFile raf;
+    private final Header header;
+    private final LoadCommand[] loadCommands;
+
+    private MachOAccess(RandomAccessFile raf) throws IOException {
+        this.raf = raf;
+        this.header = new Header();
+        this.loadCommands = getLoadCommands();
+    }
+
+    static LLVM_IR[] getLLVMIR(String path) throws IOException {
+        try (MachOAccess ma = new MachOAccess(new RandomAccessFile(path, "r"))) {
+            return ma.getLLVMIR();
+        }
+    }
+
+    /**
+     * Return an array of {@link LLVM_IR} instances corresponding to the "modules" in the library,
+     * or {@code null} of there none.
+     */
+    private LLVM_IR[] getLLVMIR() throws IOException {
+        SymTabLoadCommand symtab = null;
+        for (LoadCommand lc : loadCommands) {
+            if (lc.cmd == LC_TYPE.LC_SYMTAB) {
+                symtab = (SymTabLoadCommand) lc;
+                break;
+            }
+        }
+        assert symtab != null;
+        ArrayList<LLVM_IR> list = new ArrayList<>();
+        NList64[] syms = symtab.getSymbolTable();
+        for (NList64 sym : syms) {
+            String name = symtab.getSymbolName(sym);
+            if (name.startsWith("__llvm_")) {
+                String module = name.substring(7);
+                getSection(loadCommands, sym.sect);
+                raf.seek(sym.value);
+                int type = raf.read();
+                int len = readInt();
+                byte[] buf = new byte[len];
+                // exported symbols
+                String[] exports = readXXPorts();
+                // imported symbols
+                String[] imports = readXXPorts();
+                raf.read(buf);
+                LLVM_IR ir;
+                if (type == LLVM_IR.TEXT_CODE) {
+                    ir = new LLVM_IR.Text(module, new String(buf), exports, imports);
+                } else if (type == LLVM_IR.BINARY_CODE) {
+                    ir = new LLVM_IR.Binary(module, buf, exports, imports);
+                } else {
+                    throw RInternalError.shouldNotReachHere();
+                }
+                list.add(ir);
+            }
+        }
+        if (list.size() == 0) {
+            return null;
+        } else {
+            LLVM_IR[] result = new LLVM_IR[list.size()];
+            list.toArray(result);
+            return result;
+        }
+    }
+
+    String[] readXXPorts() throws IOException {
+        int numxxports = readInt();
+        String[] xxports = new String[numxxports];
+        for (int i = 0; i < numxxports; i++) {
+            int xxportLen = raf.read();
+            byte[] xxportBuf = new byte[xxportLen];
+            for (int j = 0; j < xxportLen; j++) {
+                xxportBuf[j] = (byte) raf.read();
+            }
+            xxports[i] = new String(xxportBuf);
+        }
+        return xxports;
+    }
+
+    @Override
+    public void close() throws IOException {
+        raf.close();
+    }
+
+    private final class Header implements Cloneable {
+        private static final int FAT_MAGIC = 0xcafebabe;
+        private final int magic;
+        private final int cputype;
+        private final int cpusubtype;
+        private final int filetype;
+        private final int ncmds;
+        private final int sizeofcmds;
+        private final int flags;
+        private final int reserved;
+
+        private Header() throws IOException {
+            this.magic = raf.readInt();
+            assert magic != FAT_MAGIC;
+            cputype = readInt();
+            cpusubtype = readInt();
+            filetype = readInt();
+            ncmds = readInt();
+            sizeofcmds = readInt();
+            flags = readInt();
+            reserved = readInt();
+        }
+
+    }
+
+    private enum LC_TYPE {
+        LC_SYMTAB(0x2),
+        LC_THREAD(0x4),
+        LC_DYSYMTAB(0xb),
+        LC_LOAD_DYLIB(0xc),
+        LC_ID_DYLIB(0xd),
+        LC_SUB_FRAMEWORK(0x12),
+        LC_SEGMENT_64(0x19),
+        LC_UUID(0x1b),
+        LC_RPATH(0x1C),
+        LC_DYLD_INFO(0x22),
+        LC_VERSION_MIN_MACOSX(0x24),
+        LC_FUNCTION_STARTS(0x26),
+        LC_DATA_IN_CODE(0x29),
+        LC_SOURCE_VERSION(0x2A),
+        LC_USER(0x32);
+
+        private int code;
+
+        LC_TYPE(int code) {
+            this.code = code;
+        }
+
+        static int getCode(int codeIn) {
+            return codeIn & ~LoadCommand.LC_REQ_DYLD;
+        }
+
+        static LC_TYPE getType(int code) {
+            for (LC_TYPE lct : LC_TYPE.values()) {
+                if (code == lct.code) {
+                    return lct;
+                }
+            }
+            assert false : "unknown load cmd: " + code;
+            return null;
+        }
+    }
+
+    /**
+     * Common base class for all Mach-O load command types.
+     */
+    private class LoadCommand {
+        private static final int LC_REQ_DYLD = 0x80000000;
+
+        private long cmdFileOffset;
+        private final int code;
+        private final LC_TYPE cmd;
+        private final int cmdsize;
+
+        protected LoadCommand(int index) throws IOException {
+            cmdFileOffset = raf.getFilePointer();
+            this.code = readInt();
+            this.cmd = LC_TYPE.getType(LC_TYPE.getCode(this.code));
+            this.cmdsize = readInt();
+        }
+
+        protected LoadCommand(int index, LC_TYPE cmd, int cmdsize) {
+            this.cmd = cmd;
+            this.code = cmd.code;
+            this.cmdsize = cmdsize;
+        }
+
+        private String typeName() {
+            return cmd.name();
+        }
+    }
+
+    /**
+     * Reads a load command structure starting at the current file position, invoking the
+     * appropriate subclass {@code read} command, based on the {@code cmd} field. Leaves the file
+     * pointer at the next load command (if any).
+     *
+     * @return instance of the appropriate subclass for discovered command type
+     * @throws IOException
+     */
+    private LoadCommand readNextLoadCommand(int index) throws IOException {
+        LoadCommand result = null;
+        final long ptr = raf.getFilePointer();
+        final LC_TYPE cmd = LC_TYPE.getType(LC_TYPE.getCode(readInt()));
+        final int cmdsize = readInt();
+        /* The LoadCommand class reads the two prior fields again. */
+        raf.seek(ptr);
+        switch (cmd) {
+            case LC_SEGMENT_64:
+                result = new Segment64LoadCommand(index);
+                break;
+            case LC_SYMTAB:
+                result = new SymTabLoadCommand(index);
+                break;
+            default:
+                result = new LoadCommand(index);
+                break;
+        }
+        // skip over entire command
+        raf.seek(ptr + cmdsize);
+        return result;
+    }
+
+    private LoadCommand[] getLoadCommands() throws IOException {
+        LoadCommand[] result = new LoadCommand[header.ncmds];
+        for (int i = 0; i < header.ncmds; i++) {
+            result[i] = readNextLoadCommand(i);
+        }
+        return result;
+    }
+
+    private final class Segment64LoadCommand extends LoadCommand {
+        private final String segName;
+        private final long vmaddr;
+        private final long vmsize;
+        private final long fileoff;
+        private final long filesize;
+        private final int maxprot;
+        private final int initprot;
+        private final int nsects;
+        private final int flags;
+        private final Section64[] sections;
+
+        private Segment64LoadCommand(int index) throws IOException {
+            super(index);
+            final byte[] segname = new byte[16];
+            for (int i = 0; i < 16; i++) {
+                segname[i] = raf.readByte();
+            }
+            segName = new String(segname);
+            vmaddr = readLong();
+            vmsize = readLong();
+            fileoff = readLong();
+            filesize = readLong();
+            maxprot = readInt();
+            initprot = readInt();
+            nsects = readInt();
+            flags = readInt();
+            sections = new Section64[nsects];
+            for (int i = 0; i < nsects; i++) {
+                sections[i] = new Section64(this);
+            }
+        }
+
+    }
+
+    private final class Section64 {
+        private final String sectname;
+        private final String segname;
+        private final long addr;
+        private final long size;
+        private final int offset;
+        private final int align;
+        private final int reloff;
+        private final int nreloc;
+        private final int flags;
+        private final int reserved1;
+        private final int reserved2;
+        private final int reserved3;
+
+        private Section64(Segment64LoadCommand segment64) throws IOException {
+            sectname = readName();
+            segname = readName();
+            addr = readLong();
+            size = readLong();
+            offset = readInt();
+            align = readInt();
+            reloff = readInt();
+            nreloc = readInt();
+            flags = readInt();
+            reserved1 = readInt();
+            reserved2 = readInt();
+            reserved3 = readInt();
+        }
+
+        private String readName() throws IOException {
+            byte[] nameBytes = new byte[16];
+            int length = 0;
+            for (int i = 0; i < nameBytes.length; i++) {
+                nameBytes[i] = raf.readByte();
+                if (nameBytes[i] != 0) {
+                    length++;
+                }
+            }
+            return new String(nameBytes, 0, length);
+        }
+
+        private boolean isText() {
+            return segname.equals("__TEXT");
+        }
+    }
+
+    private class SymTabLoadCommand extends LoadCommand {
+        private final int symoff;
+        private final int nsyms;
+        private final int stroff;
+        private final int strsize;
+        /**
+         * Lazily created string table.
+         */
+        private byte[] stringTable;
+        /**
+         * Lazily created symbol table.
+         */
+        private NList64[] symbolTable;
+
+        SymTabLoadCommand(int index) throws IOException {
+            super(index);
+            symoff = readInt();
+            nsyms = readInt();
+            stroff = readInt();
+            strsize = readInt();
+        }
+
+        private NList64[] getSymbolTable() throws IOException {
+            if (symbolTable != null) {
+                return symbolTable;
+            }
+            stringTable = new byte[strsize];
+            raf.seek(stroff);
+            for (int i = 0; i < strsize; i++) {
+                stringTable[i] = raf.readByte();
+            }
+            symbolTable = new NList64[nsyms];
+            raf.seek(symoff);
+            for (int i = 0; i < nsyms; i++) {
+                symbolTable[i] = new NList64();
+            }
+            return symbolTable;
+        }
+
+        private String getSymbolName(NList64 nlist64) {
+            String symbol = "";
+            if (nlist64.strx != 0) {
+                byte sb = stringTable[nlist64.strx];
+                int sl = 0;
+                while (sb != 0) {
+                    sb = stringTable[nlist64.strx + sl];
+                    sl++;
+                }
+                if (sl > 0) {
+                    symbol = new String(stringTable, nlist64.strx, sl - 1);
+                }
+            }
+            return symbol;
+        }
+
+    }
+
+    private class NList64 {
+        private final int strx;
+        private final byte type;
+        private final byte sect;
+        private final short desc;
+        private final long value;
+
+        NList64() throws IOException {
+            strx = readInt();
+            type = raf.readByte();
+            sect = raf.readByte();
+            desc = readShort();
+            value = readLong();
+        }
+
+        void print() {
+
+        }
+    }
+
+    /**
+     * Locates a given section within a given array of load commands. Sections are numbered from 1
+     * as they occur within SEGMENT_64 commands.
+     *
+     * @param loadCommands
+     * @param sectToFind
+     */
+    private static Section64 getSection(LoadCommand[] loadCommands, int sectToFind) {
+        int sect = 1;
+        for (int i = 0; i < loadCommands.length; i++) {
+            if (loadCommands[i].cmd == LC_TYPE.LC_SEGMENT_64) {
+                Segment64LoadCommand slc = (Segment64LoadCommand) loadCommands[i];
+                if (sectToFind < sect + slc.nsects) {
+                    return slc.sections[sectToFind - sect];
+                }
+                sect += slc.nsects;
+            }
+        }
+        return null;
+    }
+
+    private short readShort() throws IOException {
+        final int b1 = raf.read();
+        final int b2 = raf.read();
+        return (short) (((b2 << 8) | b1) & 0xFFFF);
+    }
+
+    private int readInt() throws IOException {
+        final int b1 = raf.read();
+        final int b2 = raf.read();
+        final int b3 = raf.read();
+        final int b4 = raf.read();
+        return (b4 << 24) | (b3 << 16) | (b2 << 8) | b1;
+    }
+
+    private long readLong() throws IOException {
+        final long lw = readInt();
+        final long hw = readInt();
+        return hw << 32 | (lw & 0xFFFFFFFFL);
+    }
+
+}
diff --git a/com.oracle.truffle.r.runtime.ffi/src/com/oracle/truffle/r/runtime/ffi/truffle/TruffleRFFIFrameHelper.java b/com.oracle.truffle.r.runtime.ffi/src/com/oracle/truffle/r/runtime/ffi/truffle/TruffleRFFIFrameHelper.java
new file mode 100644
index 0000000000000000000000000000000000000000..6b892a78508eb4b640a63e20b5836ba5136b4718
--- /dev/null
+++ b/com.oracle.truffle.r.runtime.ffi/src/com/oracle/truffle/r/runtime/ffi/truffle/TruffleRFFIFrameHelper.java
@@ -0,0 +1,33 @@
+/*
+ * Copyright (c) 2014, 2016, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package com.oracle.truffle.r.runtime.ffi.truffle;
+
+import com.oracle.truffle.api.frame.VirtualFrame;
+import com.oracle.truffle.r.runtime.SubstituteVirtualFrame;
+import com.oracle.truffle.r.runtime.Utils;
+
+public class TruffleRFFIFrameHelper {
+    public static VirtualFrame create() {
+        return SubstituteVirtualFrame.create(Utils.getActualCurrentFrame().materialize());
+    }
+}
diff --git a/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/FastROptions.java b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/FastROptions.java
index f0005b639aa32fc19806700f8fc22b15120367ad..767d9529d17dc088decc4f2074ea812f7b27f6bf 100644
--- a/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/FastROptions.java
+++ b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/FastROptions.java
@@ -53,6 +53,7 @@ public enum FastROptions {
     RefCountIncrementOnly("Disable reference count decrements for experimental state transition implementation", false),
     UseInternalGraphics("Whether the internal (Java) graphics subsystem should be used", false),
     UseSpecials("Whether the fast-path special call nodes should be created for simple enough arguments.", true),
+    ForceSources("Generate source sections for unserialized code", false),
 
     // Promises optimizations
     EagerEval("If enabled, overrides all other EagerEval switches (see EagerEvalHelper)", false),
diff --git a/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/RCompression.java b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/RCompression.java
index 785970bd521f4d6985aa39935494d65c5a51df3a..ca59c7286623759f03f7c9623aa1f4af9a706e41 100644
--- a/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/RCompression.java
+++ b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/RCompression.java
@@ -22,14 +22,19 @@
  */
 package com.oracle.truffle.r.runtime;
 
+import java.io.ByteArrayInputStream;
 import java.io.FileInputStream;
 import java.io.IOException;
 import java.io.InputStream;
 import java.io.OutputStream;
 import java.lang.ProcessBuilder.Redirect;
+import java.nio.file.Files;
+import java.nio.file.OpenOption;
+import java.nio.file.Paths;
+import java.nio.file.StandardOpenOption;
+import java.util.Arrays;
 import java.util.zip.GZIPInputStream;
-
-import com.oracle.truffle.r.runtime.conn.GZIPConnections.GZIPRConnection;
+import org.tukaani.xz.LZMA2InputStream;
 import com.oracle.truffle.r.runtime.ffi.RFFIFactory;
 
 /**
@@ -41,7 +46,7 @@ public class RCompression {
         NONE('0'),
         GZIP('1'),
         BZIP2('2'),
-        LZMA('Z');
+        XZ('Z');
 
         public final byte typeByte;
 
@@ -70,7 +75,7 @@ public class RCompression {
             } else if (buf[0] == 'B' && buf[1] == 'Z' && buf[2] == 'h') {
                 return RCompression.Type.BZIP2;
             } else if (buf[0] == (byte) 0xFD && buf[1] == '7' && buf[2] == 'z' && buf[3] == 'X' && buf[4] == 'Z') {
-                return RCompression.Type.LZMA;
+                return RCompression.Type.XZ;
             } else {
                 return RCompression.Type.NONE;
             }
@@ -88,6 +93,15 @@ public class RCompression {
         return RCompression.Type.NONE;
     }
 
+    /**
+     * Uncompress for internal use in {@code LazyLoadDBFetch} where size of uncompressed data is
+     * known.
+     *
+     * @param type compression type
+     * @param udata where to store uncompressed data
+     * @param cdata data to uncompress
+     * @return {@code true} iff success
+     */
     public static boolean uncompress(Type type, byte[] udata, byte[] cdata) {
         switch (type) {
             case NONE:
@@ -97,7 +111,7 @@ public class RCompression {
                 return gzipUncompress(udata, cdata);
             case BZIP2:
                 throw RInternalError.unimplemented("BZIP2 compression");
-            case LZMA:
+            case XZ:
                 return lzmaUncompress(udata, cdata);
             default:
                 assert false;
@@ -105,6 +119,15 @@ public class RCompression {
         }
     }
 
+    /**
+     * Uncompress for internal use in {@code LazyLoadDBInsertValue} where size of uncompressed data
+     * is known.
+     *
+     * @param type compression type
+     * @param udata uncompressed data
+     * @param cdata where to store compressed data
+     * @return {@code true} iff success
+     */
     public static boolean compress(Type type, byte[] udata, byte[] cdata) {
         switch (type) {
             case NONE:
@@ -114,7 +137,7 @@ public class RCompression {
                 return gzipCompress(udata, cdata);
             case BZIP2:
                 throw RInternalError.unimplemented("BZIP2 compression");
-            case LZMA:
+            case XZ:
                 return lzmaCompress(udata, cdata);
             default:
                 assert false;
@@ -132,6 +155,10 @@ public class RCompression {
         return rc == 0;
     }
 
+    /**
+     * There is no obvious counterpart to {@link LZMA2InputStream} and according to the XZ forum it
+     * is not implemented for Java, so have to use sub-process.
+     */
     private static boolean lzmaCompress(byte[] udata, byte[] cdata) {
         int rc;
         ProcessBuilder pb = new ProcessBuilder("xz", "--compress", "--format=raw", "--lzma2", "--stdout");
@@ -157,67 +184,64 @@ public class RCompression {
     }
 
     private static boolean lzmaUncompress(byte[] udata, byte[] data) {
-        int rc;
-        ProcessBuilder pb = new ProcessBuilder("xz", "--decompress", "--format=raw", "--lzma2", "--stdout");
+        int dictSize = udata.length < LZMA2InputStream.DICT_SIZE_MIN ? LZMA2InputStream.DICT_SIZE_MIN : udata.length;
+        try (LZMA2InputStream lzmaStream = new LZMA2InputStream(new ByteArrayInputStream(data), dictSize)) {
+            int totalRead = 0;
+            int n;
+            while ((n = lzmaStream.read(udata, totalRead, udata.length - totalRead)) > 0) {
+                totalRead += n;
+            }
+            return totalRead == udata.length;
+        } catch (IOException ex) {
+            return false;
+        }
+    }
+
+    public static byte[] bzipUncompressFromFile(String path) throws IOException {
+        String[] command = new String[]{"bzip2", "-dc", path};
+        ProcessBuilder pb = new ProcessBuilder(command);
         pb.redirectError(Redirect.INHERIT);
+        Process p = pb.start();
+        InputStream is = p.getInputStream();
+        ProcessOutputManager.OutputThreadVariable readThread = new ProcessOutputManager.OutputThreadVariable(command[0], is);
+        readThread.start();
         try {
-            Process p = pb.start();
-            OutputStream os = p.getOutputStream();
-            InputStream is = p.getInputStream();
-            ProcessOutputManager.OutputThread readThread = new ProcessOutputManager.OutputThreadFixed("xz", is, udata);
-            readThread.start();
-            os.write(data);
-            os.close();
-            rc = p.waitFor();
+            int rc = p.waitFor();
             if (rc == 0) {
                 readThread.join();
-                if (readThread.totalRead != udata.length) {
-                    return false;
-                }
+                return Arrays.copyOf(readThread.getData(), readThread.getTotalRead());
             }
-        } catch (InterruptedException | IOException ex) {
-            return false;
+        } catch (InterruptedException ex) {
+            // fall through
         }
-        return rc == 0;
-    }
-
-    /**
-     * This is used by {@link GZIPRConnection}.
-     */
-    public static byte[] lzmaUncompressFromFile(String path) {
-        return genericUncompressFromFile(new String[]{"xz", "--decompress", "--lzma2", "--stdout", path});
-    }
-
-    public static byte[] bzipUncompressFromFile(String path) {
-        return genericUncompressFromFile(new String[]{"bzip2", "-dc", path});
+        throw new IOException();
     }
 
-    private static byte[] genericUncompressFromFile(String[] command) {
+    public static void bzipCompressToFile(byte[] data, String path, boolean append) throws IOException {
+        String[] command = new String[]{"bzip2", "-zc"};
         int rc;
         ProcessBuilder pb = new ProcessBuilder(command);
         pb.redirectError(Redirect.INHERIT);
+        Process p = pb.start();
+        InputStream is = p.getInputStream();
+        OutputStream os = p.getOutputStream();
+        ProcessOutputManager.OutputThreadVariable readThread = new ProcessOutputManager.OutputThreadVariable(command[0], is);
+        readThread.start();
+        os.write(data);
+        os.close();
         try {
-            Process p = pb.start();
-            InputStream is = p.getInputStream();
-            ProcessOutputManager.OutputThreadVariable readThread = new ProcessOutputManager.OutputThreadVariable(command[0], is);
-            readThread.start();
             rc = p.waitFor();
             if (rc == 0) {
                 readThread.join();
-                return readThread.getData();
+                byte[] cData = Arrays.copyOf(readThread.getData(), readThread.getTotalRead());
+                OpenOption[] openOptions = append ? new OpenOption[]{StandardOpenOption.APPEND} : new OpenOption[0];
+                Files.write(Paths.get(path), cData, openOptions);
+                return;
             }
-        } catch (InterruptedException | IOException ex) {
+        } catch (InterruptedException ex) {
             // fall through
         }
-        throw RInternalError.shouldNotReachHere(join(command));
+        throw new IOException();
     }
 
-    private static String join(String[] args) {
-        StringBuilder sb = new StringBuilder();
-        for (String s : args) {
-            sb.append(s);
-            sb.append(' ');
-        }
-        return sb.toString();
-    }
 }
diff --git a/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/RError.java b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/RError.java
index 9337e810d8a898aa8f6c1257525fdbbbdce62cdb..1524ea35092e4342ddb353de67224bf76cc223cb 100644
--- a/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/RError.java
+++ b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/RError.java
@@ -281,6 +281,12 @@ public final class RError extends RuntimeException {
         LINE_ELEMENTS("line %d did not have %d elements"),
         ITEMS_NOT_MULTIPLE("number of items read is not a multiple of the number of columns"),
         TRACEMEM_NOT_NULL("cannot trace NULL"),
+        INPUT_MUST_BE_STRING("input must be a character string"),
+        // mathlib errors/warnings
+        ML_ERROR_RANGE("value out of range in '%s'"),
+        ML_ERROR_NOCONV("convergence failed in '%s'"),
+        ML_ERROR_PRECISION("full precision may not have been achieved in '%s'"),
+        ML_ERROR_UNDERFLOW("underflow occurred in '%s'"),
         // below: GNU R gives also expression for the argument
         NOT_FUNCTION("'%s' is not a function, character or symbol"),
         NOT_A_FUNCTION("'%s' is not a function"),
@@ -526,6 +532,8 @@ public final class RError extends RuntimeException {
         NA_IN_PROB_VECTOR("NA in probability vector"),
         NEGATIVE_PROBABILITY("negative probability"),
         NO_POSITIVE_PROBABILITIES("no positive probabilities"),
+        QBETA_ACURACY_WARNING("qbeta(a, *) =: x0 with |pbeta(x0,*%s) - alpha| = %.5g is not accurate"),
+        PCHISQ_NOT_CONVERGED_WARNING("pnchisq(x=%g, ..): not converged in %d iter."),
         NON_POSITIVE_FILL("non-positive 'fill' argument will be ignored"),
         MUST_BE_ONE_BYTE("invalid %s: must be one byte"),
         INVALID_DECIMAL_SEP("invalid decimal separator"),
@@ -565,6 +573,7 @@ public final class RError extends RuntimeException {
         RECURSIVE_INDEXING_FAILED("recursive indexing failed at level %d"),
         ARGUMENTS_PASSED("%d arguments passed to '%s' which requires %d"),
         ARGUMENTS_PASSED_0_1("0 arguments passed to '%s' which requires 1"),
+        ARGUMENTS_PASSED_INTERNAL_0_1("0 arguments passed to .Internal(%s) which requires 1"),
         ARGUMENT_IGNORED("argument '%s' will be ignored"),
         NOT_CHARACTER_VECTOR("'%s' must be a character vector"),
         WRONG_WINSLASH("'winslash' must be '/' or '\\\\\\\\'"),
diff --git a/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/RErrorHandling.java b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/RErrorHandling.java
index af99cbf6c7b6d7d62046e0d61ddd373c17a9866a..6b055c7debfdeefaa0b4d6e0bf930a149c029d47 100644
--- a/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/RErrorHandling.java
+++ b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/RErrorHandling.java
@@ -215,6 +215,16 @@ public class RErrorHandling {
         errorHandlingState.restartStack = savedRestartStack;
     }
 
+    public static void restoreHandlerStack(Object savedHandlerStack) {
+        ContextStateImpl errorHandlingState = getRErrorHandlingState();
+        errorHandlingState.handlerStack = savedHandlerStack;
+    }
+
+    public static void restoreRestartStack(Object savedRestartStack) {
+        ContextStateImpl errorHandlingState = getRErrorHandlingState();
+        errorHandlingState.restartStack = savedRestartStack;
+    }
+
     public static Object createHandlers(RAbstractStringVector classes, RList handlers, REnvironment parentEnv, Object target, byte calling) {
         CompilerAsserts.neverPartOfCompilation();
         Object oldStack = getRestartStack();
@@ -624,7 +634,7 @@ public class RErrorHandling {
                 throw RInternalError.unimplemented();
             } else if (w == 1) {
                 Utils.writeStderr(message, true);
-            } else if (w == 0) {
+            } else if (w == 0 && errorHandlingState.warnings.size() < errorHandlingState.maxWarnings) {
                 errorHandlingState.warnings.add(new Warning(fmsg, call));
             }
         } finally {
@@ -685,7 +695,8 @@ public class RErrorHandling {
                 if (nWarnings < errorHandlingState.maxWarnings) {
                     Utils.writeStderr(String.format("There were %d warnings (use warnings() to see them)", nWarnings), true);
                 } else {
-                    Utils.writeStderr(String.format("There were %d or more warnings (use warnings() to see the first %d)", nWarnings, errorHandlingState.maxWarnings), true);
+                    assert nWarnings == errorHandlingState.maxWarnings : "warnings above the limit should not have been added";
+                    Utils.writeStderr(String.format("There were %d or more warnings (use warnings() to see the first %d)", nWarnings, nWarnings), true);
                 }
             }
             Object[] wData = new Object[nWarnings];
diff --git a/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/RRuntime.java b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/RRuntime.java
index 8bda754072cca500331e96578fc6d16d533b4073..ea4b1ef78ecb089c201293265209f913f7c82dd5 100644
--- a/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/RRuntime.java
+++ b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/RRuntime.java
@@ -512,15 +512,19 @@ public class RRuntime {
         return isNA(i) ? createComplexNA() : int2complexNoCheck(i);
     }
 
-    @TruffleBoundary
     public static String intToStringNoCheck(int operand) {
         if (operand >= MIN_CACHED_NUMBER && operand <= MAX_CACHED_NUMBER) {
             return numberStringCache[operand - MIN_CACHED_NUMBER];
         } else {
-            return String.valueOf(operand);
+            return intToStringInternal(operand);
         }
     }
 
+    @TruffleBoundary
+    private static String intToStringInternal(int operand) {
+        return String.valueOf(operand);
+    }
+
     public static boolean isCachedNumberString(int value) {
         return value >= MIN_CACHED_NUMBER && value <= MAX_CACHED_NUMBER;
     }
diff --git a/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/RSerialize.java b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/RSerialize.java
index 88c9bc23ee170a940db7ad22673a263e0f771b9d..3cfaeb8f1ef3c197eae8b310ac86663dfdf6365a 100644
--- a/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/RSerialize.java
+++ b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/RSerialize.java
@@ -458,8 +458,12 @@ public class RSerialize {
                      * only used in a warning message in the unlikely event that the namespace
                      * cannot be found.
                      */
-                    Object r = RContext.getEngine().evalFunction(contextState.getDotDotFindNamespace(), null, null, null, s, "");
-                    return checkResult(addReadRef(r));
+                    // fast path through getRegisteredNamespace
+                    Object namespace = REnvironment.getRegisteredNamespace(s.getDataAt(0));
+                    if (namespace == null) {
+                        namespace = RContext.getEngine().evalFunction(contextState.getDotDotFindNamespace(), null, null, null, s, "");
+                    }
+                    return checkResult(addReadRef(namespace));
                 }
 
                 case PERSISTSXP: {
diff --git a/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/Utils.java b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/Utils.java
index 2562d2a0cb7881d5082219922dec5532d14746f9..f4f61fb5edcf57d2c3ffa6a1f4b517f9fd675de2 100644
--- a/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/Utils.java
+++ b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/Utils.java
@@ -550,48 +550,58 @@ public final class Utils {
     }
 
     private static void dumpFrame(StringBuilder str, CallTarget callTarget, Frame frame, boolean printFrameSlots, boolean isVirtual) {
-        if (str.length() > 0) {
-            str.append("\n");
-        }
-        Frame unwrapped = RArguments.unwrap(frame);
-        if (!RArguments.isRFrame(unwrapped)) {
-            if (unwrapped.getArguments().length == 0) {
-                str.append("<empty frame>");
-            } else {
-                str.append("<unknown frame>");
-            }
-        } else {
-            if (callTarget.toString().equals("<promise>")) {
-                /* these have the same depth as the next frame, and add no useful info. */
-                return;
-            }
-            RCaller call = RArguments.getCall(unwrapped);
-            if (call != null) {
-                String callSrc = call.isValidCaller() ? RContext.getRRuntimeASTAccess().getCallerSource(call) : "<invalid call>";
-                int depth = RArguments.getDepth(unwrapped);
-                str.append("Frame(d=").append(depth).append("): ").append(callTarget).append(isVirtual ? " (virtual)" : "");
-                str.append(" (called as: ").append(callSrc).append(')');
+        try {
+            CompilerAsserts.neverPartOfCompilation();
+            if (str.length() > 0) {
+                str.append("\n");
             }
-            if (printFrameSlots) {
-                FrameDescriptor frameDescriptor = unwrapped.getFrameDescriptor();
-                for (FrameSlot s : frameDescriptor.getSlots()) {
-                    str.append("\n      ").append(s.getIdentifier()).append(" = ");
-                    Object value = unwrapped.getValue(s);
-                    try {
-                        if (value instanceof RAbstractContainer && ((RAbstractContainer) value).getLength() > 32) {
-                            str.append('<').append(value.getClass().getSimpleName()).append(" with ").append(((RAbstractContainer) value).getLength()).append(" elements>");
-                        } else {
-                            String text = String.valueOf(value);
-                            str.append(text.length() < 256 ? text : text.substring(0, 256) + "...");
+            Frame unwrapped = RArguments.unwrap(frame);
+            if (!RArguments.isRFrame(unwrapped)) {
+                if (unwrapped.getArguments().length == 0) {
+                    str.append("<empty frame>");
+                } else {
+                    str.append("<unknown frame>");
+                }
+            } else {
+                if (callTarget.toString().equals("<promise>")) {
+                    /* these have the same depth as the next frame, and add no useful info. */
+                    return;
+                }
+                RCaller call = RArguments.getCall(unwrapped);
+                if (call != null) {
+                    String callSrc = call.isValidCaller() ? RContext.getRRuntimeASTAccess().getCallerSource(call) : "<invalid call>";
+                    int depth = RArguments.getDepth(unwrapped);
+                    str.append("Frame(d=").append(depth).append("): ").append(callTarget).append(isVirtual ? " (virtual)" : "");
+                    str.append(" (called as: ").append(callSrc).append(')');
+                }
+                if (printFrameSlots) {
+                    FrameDescriptor frameDescriptor = unwrapped.getFrameDescriptor();
+                    for (FrameSlot s : frameDescriptor.getSlots()) {
+                        str.append("\n      ").append(s.getIdentifier()).append(" = ");
+                        Object value;
+                        try {
+                            value = unwrapped.getValue(s);
+                        } catch (Throwable t) {
+                            str.append("<exception ").append(t.getClass().getSimpleName()).append(" while acquiring slot ").append(s.getIdentifier()).append(">");
+                            continue;
+                        }
+                        try {
+                            if (value instanceof RAbstractContainer && ((RAbstractContainer) value).getLength() > 32) {
+                                str.append('<').append(value.getClass().getSimpleName()).append(" with ").append(((RAbstractContainer) value).getLength()).append(" elements>");
+                            } else {
+                                String text = String.valueOf(value);
+                                str.append(text.length() < 256 ? text : text.substring(0, 256) + "...");
+                            }
+                        } catch (Throwable t) {
+                            // RLanguage values may not react kindly to getLength() calls
+                            str.append("<exception ").append(t.getClass().getSimpleName()).append(" while printing value of type ").append(
+                                            value == null ? "null" : value.getClass().getSimpleName()).append('>');
                         }
-                    } catch (Throwable t) {
-                        // RLanguage values may not react kindly to getLength() calls
-                        str.append("<exception ").append(t.getClass().getSimpleName()).append(" while printing value of type ").append(
-                                        value == null ? "null" : value.getClass().getSimpleName()).append(
-                                                        '>');
                     }
                 }
             }
+        } catch (Throwable t) {
+            str.append("<exception ").append(t.getMessage()).append(" ").append(t.getClass().getSimpleName()).append("<");
         }
     }
 
diff --git a/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/conn/GZIPConnections.java b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/conn/CompressedConnections.java
similarity index 55%
rename from com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/conn/GZIPConnections.java
rename to com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/conn/CompressedConnections.java
index 0928fe7df3d31e81432526ff5988f60fb0eebb83..4530f65c9fdf88e51cd6f695f3837f15e0fe423d 100644
--- a/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/conn/GZIPConnections.java
+++ b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/conn/CompressedConnections.java
@@ -23,6 +23,7 @@
 package com.oracle.truffle.r.runtime.conn;
 
 import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
 import java.io.FileInputStream;
 import java.io.FileOutputStream;
 import java.io.IOException;
@@ -32,8 +33,15 @@ import java.nio.ByteBuffer;
 import java.util.zip.GZIPInputStream;
 import java.util.zip.GZIPOutputStream;
 
+import org.tukaani.xz.LZMA2Options;
+import org.tukaani.xz.XZ;
+import org.tukaani.xz.XZInputStream;
+import org.tukaani.xz.XZOutputStream;
+
 import com.oracle.truffle.r.runtime.RCompression;
+import com.oracle.truffle.r.runtime.RCompression.Type;
 import com.oracle.truffle.r.runtime.RError;
+import com.oracle.truffle.r.runtime.RInternalError;
 import com.oracle.truffle.r.runtime.conn.ConnectionSupport.AbstractOpenMode;
 import com.oracle.truffle.r.runtime.conn.ConnectionSupport.BasePathRConnection;
 import com.oracle.truffle.r.runtime.conn.ConnectionSupport.ConnectionClass;
@@ -43,20 +51,42 @@ import com.oracle.truffle.r.runtime.conn.ConnectionSupport.DelegateWriteRConnect
 import com.oracle.truffle.r.runtime.conn.ConnectionSupport.ReadWriteHelper;
 import com.oracle.truffle.r.runtime.data.model.RAbstractStringVector;
 
-public class GZIPConnections {
+public class CompressedConnections {
     public static final int GZIP_BUFFER_SIZE = (2 << 20);
 
     /**
-     * Base class for all modes of gzfile connections. N.B. gzfile is defined to be able to read
-     * gzip, bzip, lzma and uncompressed files, which has to be implemented by reading the first few
-     * bytes of the file and detecting the type of the file.
+     * Base class for all modes of gzfile/bzfile/xzfile connections. N.B. In GNU R these can read
+     * gzip, bzip, lzma and uncompressed files, and this has to be implemented by reading the first
+     * few bytes of the file and detecting the type of the file.
      */
-    public static class GZIPRConnection extends BasePathRConnection {
-        public GZIPRConnection(String path, String modeString) throws IOException {
-            super(path, ConnectionClass.GZFile, modeString, AbstractOpenMode.ReadBinary);
+    public static class CompressedRConnection extends BasePathRConnection {
+        private final RCompression.Type cType;
+        @SuppressWarnings("unused") private final String encoding; // TODO
+        @SuppressWarnings("unused") private final int compression; // TODO
+
+        public CompressedRConnection(String path, String modeString, Type cType, String encoding, int compression) throws IOException {
+            super(path, mapConnectionClass(cType), modeString, AbstractOpenMode.ReadBinary);
+            this.cType = cType;
+            this.encoding = encoding;
+            this.compression = compression;
             openNonLazyConnection();
         }
 
+        private static ConnectionClass mapConnectionClass(RCompression.Type cType) {
+            switch (cType) {
+                case NONE:
+                    return ConnectionClass.File;
+                case GZIP:
+                    return ConnectionClass.GZFile;
+                case BZIP2:
+                    return ConnectionClass.BZFile;
+                case XZ:
+                    return ConnectionClass.XZFile;
+                default:
+                    throw RInternalError.shouldNotReachHere();
+            }
+        }
+
         @Override
         protected void createDelegateConnection() throws IOException {
             DelegateRConnection delegate = null;
@@ -64,8 +94,15 @@ public class GZIPConnections {
             switch (openMode) {
                 case Read:
                 case ReadBinary:
-                    RCompression.Type cType = RCompression.getCompressionType(path);
-                    switch (cType) {
+                    /*
+                     * For input, we check the actual compression type as GNU R is permissive about
+                     * the claimed type.
+                     */
+                    RCompression.Type cTypeActual = RCompression.getCompressionType(path);
+                    if (cTypeActual != cType) {
+                        updateConnectionClass(mapConnectionClass(cTypeActual));
+                    }
+                    switch (cTypeActual) {
                         case NONE:
                             if (openMode == AbstractOpenMode.ReadBinary) {
                                 delegate = new FileConnections.FileReadBinaryRConnection(this);
@@ -74,26 +111,36 @@ public class GZIPConnections {
                             }
                             break;
                         case GZIP:
-                            delegate = new GZIPInputRConnection(this);
+                            delegate = new CompressedInputRConnection(this, new GZIPInputStream(new FileInputStream(path), GZIP_BUFFER_SIZE));
                             break;
-                        case LZMA:
-                            /*
-                             * no lzma support in Java. For now we use RCompression to a byte array
-                             * and return a ByteArrayInputStream on that.
-                             */
-                            byte[] lzmaUdata = RCompression.lzmaUncompressFromFile(path);
-                            delegate = new ByteGZipInputRConnection(this, new ByteArrayInputStream(lzmaUdata));
+                        case XZ:
+                            delegate = new CompressedInputRConnection(this, new XZInputStream(new FileInputStream(path)));
                             break;
                         case BZIP2:
-                            // ditto
+                            // no in Java support, so go via byte array
                             byte[] bzipUdata = RCompression.bzipUncompressFromFile(path);
-                            delegate = new ByteGZipInputRConnection(this, new ByteArrayInputStream(bzipUdata));
+                            delegate = new ByteStreamCompressedInputRConnection(this, new ByteArrayInputStream(bzipUdata));
                     }
                     break;
+
+                case Append:
+                case AppendBinary:
                 case Write:
-                case WriteBinary:
-                    delegate = new GZIPOutputRConnection(this);
+                case WriteBinary: {
+                    boolean append = openMode == AbstractOpenMode.Append || openMode == AbstractOpenMode.AppendBinary;
+                    switch (cType) {
+                        case GZIP:
+                            delegate = new CompressedOutputRConnection(this, new GZIPOutputStream(new FileOutputStream(path, append), GZIP_BUFFER_SIZE));
+                            break;
+                        case BZIP2:
+                            delegate = new BZip2OutputRConnection(this, new ByteArrayOutputStream(), append);
+                            break;
+                        case XZ:
+                            delegate = new CompressedOutputRConnection(this, new XZOutputStream(new FileOutputStream(path, append), new LZMA2Options(), XZ.CHECK_CRC32));
+                            break;
+                    }
                     break;
+                }
                 default:
                     throw RError.nyi(RError.SHOW_CALLER2, "open mode: " + getOpenMode());
             }
@@ -109,15 +156,10 @@ public class GZIPConnections {
         // }
     }
 
-    private static class GZIPInputRConnection extends DelegateReadRConnection implements ReadWriteHelper {
+    private static class CompressedInputRConnection extends DelegateReadRConnection implements ReadWriteHelper {
         private InputStream inputStream;
 
-        GZIPInputRConnection(GZIPRConnection base) throws IOException {
-            super(base);
-            inputStream = new GZIPInputStream(new FileInputStream(base.path), GZIP_BUFFER_SIZE);
-        }
-
-        protected GZIPInputRConnection(GZIPRConnection base, InputStream is) {
+        protected CompressedInputRConnection(CompressedRConnection base, InputStream is) {
             super(base);
             this.inputStream = is;
         }
@@ -159,18 +201,18 @@ public class GZIPConnections {
         }
     }
 
-    private static class ByteGZipInputRConnection extends GZIPInputRConnection {
-        ByteGZipInputRConnection(GZIPRConnection base, ByteArrayInputStream is) {
+    private static class ByteStreamCompressedInputRConnection extends CompressedInputRConnection {
+        ByteStreamCompressedInputRConnection(CompressedRConnection base, ByteArrayInputStream is) {
             super(base, is);
         }
     }
 
-    private static class GZIPOutputRConnection extends DelegateWriteRConnection implements ReadWriteHelper {
-        private GZIPOutputStream outputStream;
+    private static class CompressedOutputRConnection extends DelegateWriteRConnection implements ReadWriteHelper {
+        protected OutputStream outputStream;
 
-        GZIPOutputRConnection(GZIPRConnection base) throws IOException {
+        protected CompressedOutputRConnection(CompressedRConnection base, OutputStream os) {
             super(base);
-            outputStream = new GZIPOutputStream(new FileOutputStream(base.path), GZIP_BUFFER_SIZE);
+            this.outputStream = os;
         }
 
         @Override
@@ -215,4 +257,25 @@ public class GZIPConnections {
             outputStream.flush();
         }
     }
+
+    private static class BZip2OutputRConnection extends CompressedOutputRConnection {
+        private final ByteArrayOutputStream bos;
+        private final boolean append;
+
+        BZip2OutputRConnection(CompressedRConnection base, ByteArrayOutputStream os, boolean append) {
+            super(base, os);
+            this.bos = os;
+            this.append = append;
+        }
+
+        @Override
+        public void close() throws IOException {
+            flush();
+            outputStream.close();
+            // Now actually do the compression using sub-process
+            byte[] data = bos.toByteArray();
+            RCompression.bzipCompressToFile(data, ((BasePathRConnection) base).path, append);
+        }
+    }
+
 }
diff --git a/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/conn/ConnectionSupport.java b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/conn/ConnectionSupport.java
index e53c581f1a97c8d6741feb1e4dbb16d038e5a219..25922b8644237f0845edce7260dae41b5560c662 100644
--- a/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/conn/ConnectionSupport.java
+++ b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/conn/ConnectionSupport.java
@@ -308,6 +308,8 @@ public class ConnectionSupport {
         Terminal("terminal"),
         File("file"),
         GZFile("gzfile"),
+        BZFile("bzfile"),
+        XZFile("xzfile"),
         Socket("sockconn"),
         Text("textConnection"),
         URL("url"),
@@ -511,7 +513,7 @@ public class ConnectionSupport {
          */
         private int descriptor;
 
-        private final ConnectionClass conClass;
+        private ConnectionClass conClass;
 
         /**
          * The constructor for every connection class except {@link StdConnections}.
@@ -548,6 +550,13 @@ public class ConnectionSupport {
             return conClass;
         }
 
+        /**
+         * {@code gzfile} can open other connection classes, and this isn't known initially.
+         */
+        public final void updateConnectionClass(ConnectionClass conClass) {
+            this.conClass = conClass;
+        }
+
         protected void openNonLazyConnection() throws IOException {
             if (openMode.abstractOpenMode != AbstractOpenMode.Lazy) {
                 createDelegateConnection();
diff --git a/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/conn/FileConnections.java b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/conn/FileConnections.java
index 0c02b5bbe9c8164f46e13be57d5b16e3ef3aeccb..0d9d532e6b8067c4cd06176db2782bde0f2c6513 100644
--- a/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/conn/FileConnections.java
+++ b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/conn/FileConnections.java
@@ -24,6 +24,7 @@ package com.oracle.truffle.r.runtime.conn;
 
 import java.io.BufferedInputStream;
 import java.io.BufferedOutputStream;
+import java.io.ByteArrayInputStream;
 import java.io.FileInputStream;
 import java.io.FileOutputStream;
 import java.io.IOException;
@@ -33,6 +34,8 @@ import java.io.RandomAccessFile;
 import java.nio.ByteBuffer;
 import java.util.zip.GZIPInputStream;
 
+import org.tukaani.xz.XZInputStream;
+
 import com.oracle.truffle.api.CompilerDirectives.TruffleBoundary;
 import com.oracle.truffle.r.runtime.RCompression;
 import com.oracle.truffle.r.runtime.RError;
@@ -110,7 +113,15 @@ public class FileConnections {
                     inputStream = new BufferedInputStream(new FileInputStream(base.path));
                     break;
                 case GZIP:
-                    inputStream = new GZIPInputStream(new FileInputStream(base.path), GZIPConnections.GZIP_BUFFER_SIZE);
+                    inputStream = new GZIPInputStream(new FileInputStream(base.path), CompressedConnections.GZIP_BUFFER_SIZE);
+                    break;
+                case BZIP2:
+                    // no in Java support, so go via byte array
+                    byte[] bzipUdata = RCompression.bzipUncompressFromFile(base.path);
+                    inputStream = new ByteArrayInputStream(bzipUdata);
+                    break;
+                case XZ:
+                    inputStream = new XZInputStream(new FileInputStream(base.path));
                     break;
                 default:
                     throw RError.nyi(RError.SHOW_CALLER2, "compression type: " + cType.name());
diff --git a/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/context/Engine.java b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/context/Engine.java
index 2e867d308647cce6bfdb76a499c4e95261cfeb45..ac6079435a58436bed6d286fe3e30f23d5048c51 100644
--- a/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/context/Engine.java
+++ b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/context/Engine.java
@@ -126,7 +126,7 @@ public interface Engine {
      * return a {@link CallTarget} which may be cached for future use, and the
      * {@link PolyglotEngine} is responsible for actually invoking the call target.
      */
-    CallTarget parseToCallTarget(Source source) throws ParseException;
+    CallTarget parseToCallTarget(Source source, MaterializedFrame executionFrame) throws ParseException;
 
     /**
      * Parse and evaluate {@code rscript} in {@code frame}. {@code printResult == true}, the result
diff --git a/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/context/RContext.java b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/context/RContext.java
index 068f49fbdfadf00ed3caae3e9556fd2ae9680bfb..9bef3f99fb205ea6c5c0a44f0ae34c68c8bb509b 100644
--- a/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/context/RContext.java
+++ b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/context/RContext.java
@@ -44,7 +44,6 @@ import com.oracle.truffle.api.frame.VirtualFrame;
 import com.oracle.truffle.api.instrumentation.Instrumenter;
 import com.oracle.truffle.api.interop.ForeignAccess;
 import com.oracle.truffle.api.interop.TruffleObject;
-import com.oracle.truffle.api.nodes.InvalidAssumptionException;
 import com.oracle.truffle.api.source.Source;
 import com.oracle.truffle.api.vm.PolyglotEngine;
 import com.oracle.truffle.r.runtime.ExitException;
@@ -685,13 +684,8 @@ public final class RContext extends ExecutionContext implements TruffleObject {
 
     public static RContext getInstance() {
         RContext context = singleContext;
-        if (context != null) {
-            try {
-                singleContextAssumption.check();
-                return context;
-            } catch (InvalidAssumptionException e) {
-                // fallback to slow case
-            }
+        if (singleContextAssumption.isValid() && context != null) {
+            return context;
         }
 
         Thread current = Thread.currentThread();
diff --git a/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/data/RAttributesLayout.java b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/data/RAttributesLayout.java
index 8f35974969087a286e79230a3b7af3788e483ff2..523100966ba101fd359421ba7c15423cbd3684e2 100644
--- a/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/data/RAttributesLayout.java
+++ b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/data/RAttributesLayout.java
@@ -22,6 +22,7 @@
  */
 package com.oracle.truffle.r.runtime.data;
 
+import java.util.Collections;
 import java.util.HashMap;
 import java.util.Iterator;
 import java.util.List;
@@ -257,6 +258,9 @@ public final class RAttributesLayout {
     }
 
     public static final class RAttributeIterable implements Iterable<RAttributesLayout.RAttribute> {
+
+        public static final RAttributeIterable EMPTY = new RAttributeIterable(null, null);
+
         private final DynamicObject attrs;
         private final List<Property> properties;
 
@@ -267,7 +271,11 @@ public final class RAttributesLayout {
 
         @Override
         public Iterator<RAttributesLayout.RAttribute> iterator() {
-            return new Iter(attrs, properties.iterator());
+            if (attrs == null || properties == null) {
+                return Collections.emptyIterator();
+            } else {
+                return new Iter(attrs, properties.iterator());
+            }
         }
 
     }
diff --git a/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/data/RTypesFlatLayout.java b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/data/RTypesFlatLayout.java
new file mode 100644
index 0000000000000000000000000000000000000000..ed769f7b79bb5da49e260d32d43b057406d81318
--- /dev/null
+++ b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/data/RTypesFlatLayout.java
@@ -0,0 +1,303 @@
+/*
+ * Copyright (c) 2013, 2016, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package com.oracle.truffle.r.runtime.data;
+
+import com.oracle.truffle.api.dsl.ImplicitCast;
+import com.oracle.truffle.api.dsl.TypeCast;
+import com.oracle.truffle.api.dsl.TypeCheck;
+import com.oracle.truffle.api.dsl.TypeSystem;
+import com.oracle.truffle.api.dsl.internal.DSLOptions;
+import com.oracle.truffle.api.dsl.internal.DSLOptions.DSLGenerator;
+import com.oracle.truffle.r.runtime.data.model.RAbstractComplexVector;
+import com.oracle.truffle.r.runtime.data.model.RAbstractContainer;
+import com.oracle.truffle.r.runtime.data.model.RAbstractDoubleVector;
+import com.oracle.truffle.r.runtime.data.model.RAbstractIntVector;
+import com.oracle.truffle.r.runtime.data.model.RAbstractLogicalVector;
+import com.oracle.truffle.r.runtime.data.model.RAbstractRawVector;
+import com.oracle.truffle.r.runtime.data.model.RAbstractStringVector;
+import com.oracle.truffle.r.runtime.data.model.RAbstractVector;
+import com.oracle.truffle.r.runtime.nodes.RNode;
+
+/**
+ * Whenever you add a type {@code T} to the list below, make sure a corresponding {@code executeT()}
+ * method is added to {@link RNode}, a {@code typeof} method is added to {@code TypeoNode} and a
+ * {@code print} method added to {code PrettyPrinterNode}.
+ *
+ * @see RNode
+ */
+@TypeSystem({byte.class, int.class, double.class})
+@DSLOptions(defaultGenerator = DSLGenerator.FLAT)
+public class RTypesFlatLayout {
+
+    @TypeCheck(RNull.class)
+    public static boolean isRNull(Object value) {
+        return value == RNull.instance;
+    }
+
+    @TypeCast(RNull.class)
+    @SuppressWarnings("unused")
+    public static RNull asRNull(Object value) {
+        return RNull.instance;
+    }
+
+    @TypeCheck(RMissing.class)
+    public static boolean isRMissing(Object value) {
+        return value == RMissing.instance;
+    }
+
+    @TypeCast(RMissing.class)
+    @SuppressWarnings("unused")
+    public static RMissing asRMissing(Object value) {
+        return RMissing.instance;
+    }
+
+    @ImplicitCast
+    public static RAbstractContainer toAbstractContainer(int value) {
+        return RDataFactory.createIntVectorFromScalar(value);
+    }
+
+    @ImplicitCast
+    public static RAbstractContainer toAbstractContainer(double value) {
+        return RDataFactory.createDoubleVectorFromScalar(value);
+    }
+
+    @ImplicitCast
+    public static RAbstractContainer toAbstractContainer(RRaw value) {
+        return RDataFactory.createRawVectorFromScalar(value);
+    }
+
+    @ImplicitCast
+    public static RAbstractContainer toAbstractContainer(byte value) {
+        return RDataFactory.createLogicalVectorFromScalar(value);
+    }
+
+    @ImplicitCast
+    public static RAbstractContainer toAbstractContainer(RComplex value) {
+        return RDataFactory.createComplexVectorFromScalar(value);
+    }
+
+    @ImplicitCast
+    public static RAbstractContainer toAbstractContainer(String value) {
+        return RDataFactory.createStringVectorFromScalar(value);
+    }
+
+    @ImplicitCast
+    public static RAbstractContainer toAbstractContainer(RIntVector vector) {
+        return vector;
+    }
+
+    @ImplicitCast
+    public static RAbstractContainer toAbstractContainer(RDoubleVector vector) {
+        return vector;
+    }
+
+    @ImplicitCast
+    public static RAbstractContainer toAbstractContainer(RLogicalVector vector) {
+        return vector;
+    }
+
+    @ImplicitCast
+    public static RAbstractContainer toAbstractContainer(RComplexVector vector) {
+        return vector;
+    }
+
+    @ImplicitCast
+    public static RAbstractContainer toAbstractContainer(RRawVector vector) {
+        return vector;
+    }
+
+    @ImplicitCast
+    public static RAbstractContainer toAbstractContainer(RStringVector vector) {
+        return vector;
+    }
+
+    @ImplicitCast
+    public static RAbstractContainer toAbstractContainer(RIntSequence vector) {
+        return vector;
+    }
+
+    @ImplicitCast
+    public static RAbstractContainer toAbstractContainer(RDoubleSequence vector) {
+        return vector;
+    }
+
+    @ImplicitCast
+    public static RAbstractContainer toAbstractContainer(RList vector) {
+        return vector;
+    }
+
+    @ImplicitCast
+    public static RAbstractContainer toAbstractContainer(RAbstractVector vector) {
+        return vector;
+    }
+
+    @ImplicitCast
+    public static RAbstractVector toAbstractVector(int value) {
+        return RDataFactory.createIntVectorFromScalar(value);
+    }
+
+    @ImplicitCast
+    public static RAbstractVector toAbstractVector(double value) {
+        return RDataFactory.createDoubleVectorFromScalar(value);
+    }
+
+    @ImplicitCast
+    public static RAbstractVector toAbstractVector(RRaw value) {
+        return RDataFactory.createRawVectorFromScalar(value);
+    }
+
+    @ImplicitCast
+    public static RAbstractVector toAbstractVector(byte value) {
+        return RDataFactory.createLogicalVectorFromScalar(value);
+    }
+
+    @ImplicitCast
+    public static RAbstractVector toAbstractVector(RComplex value) {
+        return RDataFactory.createComplexVectorFromScalar(value);
+    }
+
+    @ImplicitCast
+    public static RAbstractVector toAbstractVector(String value) {
+        return RDataFactory.createStringVectorFromScalar(value);
+    }
+
+    @ImplicitCast
+    public static RAbstractVector toAbstractVector(RIntVector vector) {
+        return vector;
+    }
+
+    @ImplicitCast
+    public static RAbstractVector toAbstractVector(RDoubleVector vector) {
+        return vector;
+    }
+
+    @ImplicitCast
+    public static RAbstractVector toAbstractVector(RLogicalVector vector) {
+        return vector;
+    }
+
+    @ImplicitCast
+    public static RAbstractVector toAbstractVector(RComplexVector vector) {
+        return vector;
+    }
+
+    @ImplicitCast
+    public static RAbstractVector toAbstractVector(RRawVector vector) {
+        return vector;
+    }
+
+    @ImplicitCast
+    public static RAbstractVector toAbstractVector(RStringVector vector) {
+        return vector;
+    }
+
+    @ImplicitCast
+    public static RAbstractVector toAbstractVector(RIntSequence vector) {
+        return vector;
+    }
+
+    @ImplicitCast
+    public static RAbstractVector toAbstractVector(RDoubleSequence vector) {
+        return vector;
+    }
+
+    @ImplicitCast
+    public static RAbstractVector toAbstractVector(RList vector) {
+        return vector;
+    }
+
+    @ImplicitCast
+    public static RAbstractIntVector toAbstractIntVector(int value) {
+        return RDataFactory.createIntVectorFromScalar(value);
+    }
+
+    @ImplicitCast
+    public static RAbstractIntVector toAbstractIntVector(RIntSequence vector) {
+        return vector;
+    }
+
+    @ImplicitCast
+    public static RAbstractIntVector toAbstractIntVector(RIntVector vector) {
+        return vector;
+    }
+
+    @ImplicitCast
+    public static RAbstractDoubleVector toAbstractDoubleVector(double value) {
+        return RDataFactory.createDoubleVectorFromScalar(value);
+    }
+
+    @ImplicitCast
+    public static RAbstractDoubleVector toAbstractDoubleVector(RDoubleSequence vector) {
+        return vector;
+    }
+
+    @ImplicitCast
+    public static RAbstractDoubleVector toAbstractDoubleVector(RDoubleVector vector) {
+        return vector;
+    }
+
+    @ImplicitCast
+    public static RAbstractComplexVector toAbstractComplexVector(RComplexVector vector) {
+        return vector;
+    }
+
+    @ImplicitCast
+    public static RAbstractComplexVector toAbstractComplexVector(RComplex vector) {
+        return RDataFactory.createComplexVectorFromScalar(vector);
+    }
+
+    @ImplicitCast
+    public static RAbstractLogicalVector toAbstractLogicalVector(byte vector) {
+        return RDataFactory.createLogicalVectorFromScalar(vector);
+    }
+
+    @ImplicitCast
+    public static RAbstractLogicalVector toAbstractLogicalVector(RLogicalVector vector) {
+        return vector;
+    }
+
+    @ImplicitCast
+    public static RAbstractRawVector toAbstractRawVector(RRaw vector) {
+        return RDataFactory.createRawVectorFromScalar(vector);
+    }
+
+    @ImplicitCast
+    public static RAbstractRawVector toAbstractRawVector(RRawVector vector) {
+        return vector;
+    }
+
+    @ImplicitCast
+    public static RAbstractStringVector toAbstractStringVector(String vector) {
+        return RDataFactory.createStringVectorFromScalar(vector);
+    }
+
+    @ImplicitCast
+    public static RAbstractStringVector toAbstractStringVector(RStringVector vector) {
+        return vector;
+    }
+
+    @ImplicitCast
+    public static RMissing toRMissing(@SuppressWarnings("unused") REmpty empty) {
+        return RMissing.instance;
+    }
+}
diff --git a/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/env/frame/RFrameSlot.java b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/env/frame/RFrameSlot.java
index 81e2536a03764a896477ce6218dd8856acaaa115..e303fac170654063244a601a7b1891c87fb7e9cb 100644
--- a/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/env/frame/RFrameSlot.java
+++ b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/env/frame/RFrameSlot.java
@@ -51,5 +51,13 @@ public enum RFrameSlot {
      * each call site, the value of {@link RCaller#getVisibility()} is extracted and stored into the
      * frame slot.
      */
-    Visibility;
+    Visibility,
+    /**
+     * Used to save the handler stack in frames that modify it.
+     */
+    HandlerStack,
+    /**
+     * Used to save the restart stack in frames that modify it.
+     */
+    RestartStack
 }
diff --git a/com.oracle.truffle.r.test.native/embedded/Makefile b/com.oracle.truffle.r.test.native/embedded/Makefile
index 6496998f45135262c414513b3faa700580e214a6..f8e3d2ad094a917280195a05ea510467c47750ea 100644
--- a/com.oracle.truffle.r.test.native/embedded/Makefile
+++ b/com.oracle.truffle.r.test.native/embedded/Makefile
@@ -53,7 +53,7 @@ C_OBJECTS := $(subst $(SRC),$(OBJ),$(C_SOURCES:.c=.o))
 
 INCLUDE_DIR := $(NATIVE_PROJECT)/include
 
-all: $(OBJ)/main
+all: $(OBJ)/main Makefile
 
 $(OBJ)/main: | $(OBJ)
 
@@ -62,7 +62,7 @@ $(OBJ):
 
 
 $(OBJ)/main: $(SRC)/main.c
-	$(CC) $(CFLAGS) -I$(INCLUDE_DIR) $< -o $(OBJ)/main -L $(FASTR_LIB_DIR) -ldl -lR $(LD_FLAGS)
+	$(CC) $(CFLAGS) -I$(INCLUDE_DIR) $< -o $(OBJ)/main -L $(FASTR_LIB_DIR) -ldl -lR $(LD_FLAGS) -Wl,-rpath,$(FASTR_LIB_DIR)
 
 clean:
 	rm -rf $(OBJ)
diff --git a/com.oracle.truffle.r.test.native/packages/testrffi/testrffi/R/testrffi.R b/com.oracle.truffle.r.test.native/packages/testrffi/testrffi/R/testrffi.R
index 54c5c79209d12d65cbee830a6d24a19af28e9fc4..48d34db470d1bc751044c3411b51a433f78c5d02 100644
--- a/com.oracle.truffle.r.test.native/packages/testrffi/testrffi/R/testrffi.R
+++ b/com.oracle.truffle.r.test.native/packages/testrffi/testrffi/R/testrffi.R
@@ -78,6 +78,10 @@ rffi.r_home <- function() {
 	.Call("r_home", PACKAGE = "testrffi")
 }
 
+rffi.char_length <- function(x) {
+	.Call("char_length", PACKAGE = "testrffi", x)
+}
+
 rffi.mkStringFromChar <- function() {
 	.Call("mkStringFromChar", PACKAGE = "testrffi")
 }
diff --git a/com.oracle.truffle.r.test.native/packages/testrffi/testrffi/src/testrffi.c b/com.oracle.truffle.r.test.native/packages/testrffi/testrffi/src/testrffi.c
index 771587f95b8d1c384aa93b646a37563a6f0d1d04..b8f04f014f1932f69092eaeda8e7e26737c065e7 100644
--- a/com.oracle.truffle.r.test.native/packages/testrffi/testrffi/src/testrffi.c
+++ b/com.oracle.truffle.r.test.native/packages/testrffi/testrffi/src/testrffi.c
@@ -219,6 +219,15 @@ SEXP r_home(void) {
 	return mkString(R_Home);
 }
 
+SEXP char_length(SEXP x) {
+	const char *cx = R_CHAR(STRING_ELT(x, 0));
+	int count  = 0;
+	while (*cx++ != 0) {
+		count++;
+	}
+	return ScalarInteger(count);
+}
+
 SEXP mkStringFromChar(void) {
 	return mkString("hello");
 }
diff --git a/com.oracle.truffle.r.test.native/urand/Makefile b/com.oracle.truffle.r.test.native/urand/Makefile
index 4883c2383ea1d865cf9602546081a0ac6d4751b9..1dc8f430e262e9e052f97a98fbc7c35263b9e711 100644
--- a/com.oracle.truffle.r.test.native/urand/Makefile
+++ b/com.oracle.truffle.r.test.native/urand/Makefile
@@ -38,7 +38,7 @@ SRC = src
 C_SOURCES := $(wildcard $(SRC)/*.c)
 # Since this library is loaded explicitly we keep a consistent
 # extension so that the test script is portable for TestExpectedOutput
-C_LIBNAME := lib$(subst $(SRC)/,,$(C_SOURCES:.c=.so))
+C_LIBNAME := liburand.so
 C_OBJECTS := $(subst $(SRC),$(OBJ),$(C_SOURCES:.c=.o))
 C_LIB := $(OBJ)/$(C_LIBNAME)
 
diff --git a/com.oracle.truffle.r.test.native/urand/src/nrand.c b/com.oracle.truffle.r.test.native/urand/src/nrand.c
new file mode 100644
index 0000000000000000000000000000000000000000..9fe8ab10dbbf8a68d8db13a9258f5a8a56662d43
--- /dev/null
+++ b/com.oracle.truffle.r.test.native/urand/src/nrand.c
@@ -0,0 +1,29 @@
+/*
+ * This material is distributed under the GNU General Public License
+ * Version 2. You may review the terms of this license at
+ * http://www.gnu.org/licenses/gpl-2.0.html
+ *
+ * Copyright (c) 1995-2012, The R Core Team
+ * Copyright (c) 2003, The R Foundation
+ * Copyright (c) 2016, Oracle and/or its affiliates
+ *
+ * All rights reserved.
+ */
+#include <R_ext/Random.h>
+
+/*  ratio-of-uniforms for normal  */
+#include <math.h>
+static double x;
+
+double * user_norm_rand()
+{
+    double u, v, z;
+    do {
+        u = unif_rand();
+        v = 0.857764 * (2. * unif_rand() - 1);
+        x = v/u; z = 0.25 * x * x;
+        if (z < 1. - u) break;
+        if (z > 0.259/u + 0.35) continue;
+    } while (z > -log(u));
+    return &x;
+}
diff --git a/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/ExpectedTestOutput.test b/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/ExpectedTestOutput.test
index 8fef252e8753cf9ccc3ec41ebc0250fcd584ecfe..dc3c97220c2c5ee01180d4c307d570c1f7fae073 100644
--- a/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/ExpectedTestOutput.test
+++ b/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/ExpectedTestOutput.test
@@ -4180,7 +4180,7 @@ build   FALSE FALSE FALSE FALSE
 install FALSE FALSE FALSE FALSE
 render  FALSE FALSE FALSE FALSE
 
-##com.oracle.truffle.r.test.builtins.TestBuiltin_array.testarray11#Ignored.Unknown#
+##com.oracle.truffle.r.test.builtins.TestBuiltin_array.testarray11#
 #argv <- list(list(NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL), 8L, list(c('1', '2', '3', '4', '5', '6', '7', '8'))); .Internal(array(argv[[1]], argv[[2]], argv[[3]]))
 $`1`
 NULL
@@ -8309,6 +8309,16 @@ Error in attr(x, 42) <- NULL : 'name' must be non-null character string
 #x<-42; attr(x, NULL) <- NULL
 Error in attr(x, NULL) <- NULL : 'name' must be non-null character string
 
+##com.oracle.truffle.r.test.builtins.TestBuiltin_attrassign.testRefCount#
+#x <- c(1,2); attr(x, "foo") <- c("a","b"); y <- x; attr(x,"foo")[[1]] <- "c"; y
+[1] 1 2
+attr(,"foo")
+[1] "a" "b"
+
+##com.oracle.truffle.r.test.builtins.TestBuiltin_attrassign.testRefCount#
+#x <- c(1,2,3); y <- 42; attr(y, 'at') <- x; x[[1]] <- 2; attr(y, 'at')
+[1] 1 2 3
+
 ##com.oracle.truffle.r.test.builtins.TestBuiltin_attrassign.testattrassign1#
 #argv <- list(structure(1, foo = structure(list(a = 'a'), .Names = 'a')), 'foo', value = structure(list(a = 'a'), .Names = 'a'));`attr<-`(argv[[1]],argv[[2]],argv[[3]]);
 [1] 1
@@ -14900,6 +14910,86 @@ Error in cospi(argv[[1]]) : unimplemented complex function
 Warning message:
 In cospi(argv[[1]]) : NaNs produced
 
+##com.oracle.truffle.r.test.builtins.TestBuiltin_crc64.testCrc64#
+#.Internal(crc64('a'))
+[1] "330284772e652b05"
+
+##com.oracle.truffle.r.test.builtins.TestBuiltin_crc64.testCrc64#Ignored.ImplementationError#
+#.Internal(crc64('a', 'b'))
+Error: 2 arguments passed to .Internal(crc64) which requires 1
+
+##com.oracle.truffle.r.test.builtins.TestBuiltin_crc64.testCrc64#
+#.Internal(crc64())
+Error: 0 arguments passed to .Internal(crc64) which requires 1
+
+##com.oracle.truffle.r.test.builtins.TestBuiltin_crc64.testCrc64#
+#.Internal(crc64(01))
+Error: input must be a character string
+
+##com.oracle.truffle.r.test.builtins.TestBuiltin_crc64.testCrc64#
+#.Internal(crc64(NA))
+Error: input must be a character string
+
+##com.oracle.truffle.r.test.builtins.TestBuiltin_crc64.testCrc64#
+#.Internal(crc64(NULL))
+Error: input must be a character string
+
+##com.oracle.truffle.r.test.builtins.TestBuiltin_crc64.testCrc64#
+#.Internal(crc64(c('a')))
+[1] "330284772e652b05"
+
+##com.oracle.truffle.r.test.builtins.TestBuiltin_crc64.testCrc64#
+#.Internal(crc64(c('a', 'b')))
+[1] "330284772e652b05"
+
+##com.oracle.truffle.r.test.builtins.TestBuiltin_crc64.testCrc64#
+#.Internal(crc64(c(1, 2)))
+Error: input must be a character string
+
+##com.oracle.truffle.r.test.builtins.TestBuiltin_crc64.testCrc64#
+#.Internal(crc64(c(NULL)))
+Error: input must be a character string
+
+##com.oracle.truffle.r.test.builtins.TestBuiltin_crc64.testCrc64#
+#.Internal(crc64(double(0)))
+Error: input must be a character string
+
+##com.oracle.truffle.r.test.builtins.TestBuiltin_crc64.testCrc64#
+#.Internal(crc64(environment))
+Error: input must be a character string
+
+##com.oracle.truffle.r.test.builtins.TestBuiltin_crc64.testCrc64#
+#.Internal(crc64(integer(0)))
+Error: input must be a character string
+
+##com.oracle.truffle.r.test.builtins.TestBuiltin_crc64.testCrc64#
+#.Internal(crc64(list(NULL)))
+Error: input must be a character string
+
+##com.oracle.truffle.r.test.builtins.TestBuiltin_crc64.testCrc64#
+#.Internal(crc64(list(list())))
+Error: input must be a character string
+
+##com.oracle.truffle.r.test.builtins.TestBuiltin_crc64.testCrc64#
+#.Internal(crc64(new.env()))
+Error: input must be a character string
+
+##com.oracle.truffle.r.test.builtins.TestBuiltin_crc64.testCrc64#
+#.Internal(crc64(paste(c(letters, LETTERS, 0:9), collapse="")))
+[1] "90db9ccd9021d2d7"
+
+##com.oracle.truffle.r.test.builtins.TestBuiltin_crc64.testCrc64#
+#.Internal(crc64(stdout()))
+Error: input must be a character string
+
+##com.oracle.truffle.r.test.builtins.TestBuiltin_crc64.testCrc64#
+#crc64('a')
+Error: could not find function "crc64"
+
+##com.oracle.truffle.r.test.builtins.TestBuiltin_crc64.testCrc64#
+#crc64()
+Error: could not find function "crc64"
+
 ##com.oracle.truffle.r.test.builtins.TestBuiltin_crossprod.testCrossprod#
 #{ crossprod(1:3, matrix(1:6, ncol=2)) }
      [,1] [,2]
@@ -18612,6 +18702,14 @@ NULL
 #argv <- structure(list(expr = expression(quote(x <- c(1, x)))),     .Names = 'expr');do.call('.doTrace', argv)
 NULL
 
+##com.oracle.truffle.r.test.builtins.TestBuiltin_docall.testDoCall#Output.IgnoreErrorContext#
+#typeof(do.call(function(x) x, list(as.symbol('foo'))))
+Error in (function (x)  : object 'foo' not found
+
+##com.oracle.truffle.r.test.builtins.TestBuiltin_docall.testDoCall#
+#typeof(do.call(function(x) x, list(as.symbol('foo')), quote=TRUE))
+[1] "symbol"
+
 ##com.oracle.truffle.r.test.builtins.TestBuiltin_docall.testDoCall#
 #v1 <- as.numeric_version('3.0.0'); v2 <- as.numeric_version('3.1.0'); do.call('<', list(quote(v1), quote(v2)))
 [1] TRUE
@@ -22561,7 +22659,7 @@ attr(,"Rd_tag")
 #argv <- list(structure('BunchKaufman', class = structure('signature', package = 'methods'), .Names = 'x', package = 'methods'), structure('Matrix', .Names = 'x', package = 'Matrix', class = structure('signature', package = 'methods')), TRUE, TRUE, TRUE, TRUE, FALSE); .Internal(identical(argv[[1]], argv[[2]], argv[[3]], argv[[4]], argv[[5]], argv[[6]], argv[[7]]))
 [1] FALSE
 
-##com.oracle.truffle.r.test.builtins.TestBuiltin_identical.testidentical28#Ignored.Unknown#
+##com.oracle.truffle.r.test.builtins.TestBuiltin_identical.testidentical28#Ignored.Unstable#
 #argv <- list(structure(list(x = c(1, 1, 1, 1, 1, 1, 1, 1, 1, 1), y = c(1, 2, 3, 4, 5, 6, 7, 8, 9, 10), fac = structure(c(1L, 3L, 2L, 3L, 3L, 1L, 2L, 3L, 2L, 2L), .Label = c('A', 'B', 'C'), class = 'factor')), .Names = c('x', 'y', 'fac'), row.names = c(NA, -10L), class = 'data.frame'), structure(list(x = c(1, 1, 1, 1, 1, 1, 1, 1, 1, 1), y = c(1, 2, 3, 4, 5, 6, 7, 8, 9, 10), fac = structure(c(1L, 3L, 2L, 3L, 3L, 1L, 2L, 3L, 2L, 2L), .Label = c('A', 'B', 'C'), class = 'factor')), .Names = c('x', 'y', 'fac'), row.names = c(NA, 10L), class = 'data.frame'), TRUE, TRUE, TRUE, TRUE, FALSE); .Internal(identical(argv[[1]], argv[[2]], argv[[3]], argv[[4]], argv[[5]], argv[[6]], argv[[7]]))
 [1] TRUE
 
@@ -27555,6 +27653,12 @@ $z
 [1] 42
 
 
+##com.oracle.truffle.r.test.builtins.TestBuiltin_list.testRefCount#
+#{ l <- list(a=c(1,2)); l2 <- l; l$a[[1]] <- 3; l2 }
+$a
+[1] 1 2
+
+
 ##com.oracle.truffle.r.test.builtins.TestBuiltin_list.testlist1#
 #argv <- list(surname = structure(c('McNeil', 'Ripley', 'Ripley', 'Tierney', 'Tukey', 'Venables', 'R Core'), class = 'AsIs'), nationality = structure(c('Australia', 'UK', 'UK', 'US', 'US', 'Australia', NA), class = 'AsIs'), deceased = structure(c('no', 'no', 'no', 'no', 'yes', 'no', NA), class = 'AsIs'), title = structure(c('Interactive Data Analysis', 'Spatial Statistics', 'Stochastic Simulation', 'LISP-STAT', 'Exploratory Data Analysis', 'Modern Applied Statistics ...', 'An Introduction to R'), class = 'AsIs'), other.author = structure(c(NA, NA, NA, NA, NA, 'Ripley', 'Venables & Smith'), class = 'AsIs'));list(argv[[1]],argv[[2]],argv[[3]],argv[[4]],argv[[5]]);
 [[1]]
@@ -48181,6 +48285,12 @@ character(0)
 [1] "oo"  "bar" "ba"
 
 
+##com.oracle.truffle.r.test.builtins.TestBuiltin_strsplit.testStrSplit#
+#strsplit('Ä Ä', '[ ]', perl=TRUE)
+[[1]]
+[1] "Ä" "Ä"
+
+
 ##com.oracle.truffle.r.test.builtins.TestBuiltin_strsplit.testStrSplit#
 #{ .Internal(strsplit("7", 42, F, F, F)) }
 Error: non-character argument
@@ -48344,7 +48454,7 @@ Error: unexpected symbol in "argv <- list(c('* Edit the help file skeletons in '
 [20] "," " "
 
 
-##com.oracle.truffle.r.test.builtins.TestBuiltin_strsplit.teststrsplit3#Ignored.Unknown#
+##com.oracle.truffle.r.test.builtins.TestBuiltin_strsplit.teststrsplit3#
 #argv <- list('  \036  isSeekable() now returns FALSE on connections       which have non-default encoding.  Although documented to       record if ‘in principle’ the connection supports seeking,       it seems safer to report FALSE when it may not work.', '[ \t\n]', FALSE, TRUE, FALSE); .Internal(strsplit(argv[[1]], argv[[2]], argv[[3]], argv[[4]], argv[[5]]))
 [[1]]
  [1] ""             ""             "\036"         ""             "isSeekable()"
@@ -50514,14 +50624,10 @@ foo.bar(y, 42)
 #{ foo<-function(x, z) UseMethod("foo"); foo.baz<-function(x, z) NextMethod(); y<-1; class(y)<-c("baz", "bar"); foo.bar<-function(x, z) sys.call(0); foo(y, 42) }
 foo.bar(y, 42)
 
-##com.oracle.truffle.r.test.builtins.TestBuiltin_syscall.testSysCall#
-#{ x<-do.call(function() sys.call(0), list()); x[[1]] }
-function() sys.call(0)
-
-##com.oracle.truffle.r.test.builtins.TestBuiltin_syscall.testSysCall#
-#{ x<-do.call(function() sys.call(1), list()); list(x[[1]], x[[2]][[1]], x[[2]][[2]], x[[2]][[3]]) }
+##com.oracle.truffle.r.test.builtins.TestBuiltin_syscall.testSysCall#Output.IgnoreWhitespace#
+#{ x<-(function(f) f())(function() sys.call(1)); list(x[[1]], x[[2]][[1]], x[[2]][[2]], x[[2]][[3]]) }
 [[1]]
-do.call
+(function(f) f())
 
 [[2]]
 `function`
@@ -50533,6 +50639,10 @@ NULL
 sys.call(1)
 
 
+##com.oracle.truffle.r.test.builtins.TestBuiltin_syscall.testSysCall#
+#{ x<-do.call(function() sys.call(0), list()); x[[1]] }
+function() sys.call(0)
+
 ##com.oracle.truffle.r.test.builtins.TestBuiltin_syscalls.testSysCalls#
 #sys.calls()
 NULL
@@ -52658,7 +52768,7 @@ $lrow
 attr(,"row.names")
 [1] 1
 
-##com.oracle.truffle.r.test.builtins.TestBuiltin_unclass.testunclass26#Ignored.Unknown#
+##com.oracle.truffle.r.test.builtins.TestBuiltin_unclass.testunclass26#
 #argv <- list(structure(list(a = 1), .Dim = 1L, .Dimnames = list('a')));unclass(argv[[1]]);
 $a
 [1] 1
@@ -54472,11 +54582,54 @@ Slot "y":
 [1] 77 88
 
 
-##com.oracle.truffle.r.test.builtins.TestBuiltin_utf8ToInt.testutf8ToInt1#Ignored.Unknown#
+##com.oracle.truffle.r.test.builtins.TestBuiltin_utf8ToInt.testUtf8ToInt#
+#utf8ToInt('')
+integer(0)
+
+##com.oracle.truffle.r.test.builtins.TestBuiltin_utf8ToInt.testUtf8ToInt#
+#utf8ToInt('Hello')
+[1]  72 101 108 108 111
+
+##com.oracle.truffle.r.test.builtins.TestBuiltin_utf8ToInt.testUtf8ToInt#
+#utf8ToInt('a')
+[1] 97
+
+##com.oracle.truffle.r.test.builtins.TestBuiltin_utf8ToInt.testUtf8ToInt#
+#utf8ToInt(5)
+Error in utf8ToInt(5) : argument must be a character vector of length 1
+
+##com.oracle.truffle.r.test.builtins.TestBuiltin_utf8ToInt.testUtf8ToInt#
+#utf8ToInt(NA)
+Error in utf8ToInt(NA) : argument must be a character vector of length 1
+
+##com.oracle.truffle.r.test.builtins.TestBuiltin_utf8ToInt.testUtf8ToInt#
+#utf8ToInt(NULL)
+Error in utf8ToInt(NULL) :
+  argument must be a character vector of length 1
+
+##com.oracle.truffle.r.test.builtins.TestBuiltin_utf8ToInt.testUtf8ToInt#Output.IgnoreWhitespace#
+#utf8ToInt(c('a', 'b'))
+[1] 97
+Warning message:
+In utf8ToInt(c("a", "b")) :
+  argument should be a character vector of length 1
+all but the first element will be ignored
+
+##com.oracle.truffle.r.test.builtins.TestBuiltin_utf8ToInt.testUtf8ToInt#
+#utf8ToInt(character(0))
+Error in utf8ToInt(character(0)) :
+  argument must be a character vector of length 1
+
+##com.oracle.truffle.r.test.builtins.TestBuiltin_utf8ToInt.testUtf8ToInt#
+#utf8ToInt(numeric(0))
+Error in utf8ToInt(numeric(0)) :
+  argument must be a character vector of length 1
+
+##com.oracle.truffle.r.test.builtins.TestBuiltin_utf8ToInt.testutf8ToInt1#
 #argv <- list('lasy'); .Internal(utf8ToInt(argv[[1]]))
 [1] 108  97 115 121
 
-##com.oracle.truffle.r.test.builtins.TestBuiltin_utf8ToInt.testutf8ToInt3#Ignored.Unknown#
+##com.oracle.truffle.r.test.builtins.TestBuiltin_utf8ToInt.testutf8ToInt3#
 #argv <- structure(list(x = NA_character_), .Names = 'x');do.call('utf8ToInt', argv)
 [1] NA
 
@@ -54670,11 +54823,6 @@ NULL
 #argv <- list('raw', 0L); .Internal(vector(argv[[1]], argv[[2]]))
 raw(0)
 
-##com.oracle.truffle.r.test.builtins.TestBuiltin_warning.testwarning#
-#argv <- list('foo'); do.call('warning', argv)
-Warning message:
-In do.call("warning", argv) : foo
-
 ##com.oracle.truffle.r.test.builtins.TestBuiltin_warning.testwarning#
 #f <- function() warning('foo'); f()
 Warning message:
@@ -54685,6 +54833,11 @@ In f() : foo
 Warning message:
 In f() : foo
 
+##com.oracle.truffle.r.test.builtins.TestBuiltin_warning.testwarning#
+#warning('foo')
+Warning message:
+foo
+
 ##com.oracle.truffle.r.test.builtins.TestBuiltin_weekdaysDate.testweekdaysDate1#
 #argv <- structure(list(x = structure(16352, class = 'Date')),     .Names = 'x');do.call('weekdays.Date', argv)
 [1] "Thursday"
@@ -55084,6 +55237,66 @@ attr(,"id")
 attr(,"id")
 [1] "An Example"
 
+##com.oracle.truffle.r.test.builtins.TestBuiltin_zzfile.test1#
+#{ f <- tempfile(); c <- bzfile(f); writeLines(as.character(1:100), c); close(c); readLines(f) }
+  [1] "1"   "2"   "3"   "4"   "5"   "6"   "7"   "8"   "9"   "10"  "11"  "12"
+ [13] "13"  "14"  "15"  "16"  "17"  "18"  "19"  "20"  "21"  "22"  "23"  "24"
+ [25] "25"  "26"  "27"  "28"  "29"  "30"  "31"  "32"  "33"  "34"  "35"  "36"
+ [37] "37"  "38"  "39"  "40"  "41"  "42"  "43"  "44"  "45"  "46"  "47"  "48"
+ [49] "49"  "50"  "51"  "52"  "53"  "54"  "55"  "56"  "57"  "58"  "59"  "60"
+ [61] "61"  "62"  "63"  "64"  "65"  "66"  "67"  "68"  "69"  "70"  "71"  "72"
+ [73] "73"  "74"  "75"  "76"  "77"  "78"  "79"  "80"  "81"  "82"  "83"  "84"
+ [85] "85"  "86"  "87"  "88"  "89"  "90"  "91"  "92"  "93"  "94"  "95"  "96"
+ [97] "97"  "98"  "99"  "100"
+
+##com.oracle.truffle.r.test.builtins.TestBuiltin_zzfile.test1#
+#{ f <- tempfile(); c <- gzfile(f); writeLines(as.character(1:100), c); close(c); readLines(f) }
+  [1] "1"   "2"   "3"   "4"   "5"   "6"   "7"   "8"   "9"   "10"  "11"  "12"
+ [13] "13"  "14"  "15"  "16"  "17"  "18"  "19"  "20"  "21"  "22"  "23"  "24"
+ [25] "25"  "26"  "27"  "28"  "29"  "30"  "31"  "32"  "33"  "34"  "35"  "36"
+ [37] "37"  "38"  "39"  "40"  "41"  "42"  "43"  "44"  "45"  "46"  "47"  "48"
+ [49] "49"  "50"  "51"  "52"  "53"  "54"  "55"  "56"  "57"  "58"  "59"  "60"
+ [61] "61"  "62"  "63"  "64"  "65"  "66"  "67"  "68"  "69"  "70"  "71"  "72"
+ [73] "73"  "74"  "75"  "76"  "77"  "78"  "79"  "80"  "81"  "82"  "83"  "84"
+ [85] "85"  "86"  "87"  "88"  "89"  "90"  "91"  "92"  "93"  "94"  "95"  "96"
+ [97] "97"  "98"  "99"  "100"
+
+##com.oracle.truffle.r.test.builtins.TestBuiltin_zzfile.test1#
+#{ f <- tempfile(); c <- xzfile(f); writeLines(as.character(1:100), c); close(c); readLines(f) }
+  [1] "1"   "2"   "3"   "4"   "5"   "6"   "7"   "8"   "9"   "10"  "11"  "12"
+ [13] "13"  "14"  "15"  "16"  "17"  "18"  "19"  "20"  "21"  "22"  "23"  "24"
+ [25] "25"  "26"  "27"  "28"  "29"  "30"  "31"  "32"  "33"  "34"  "35"  "36"
+ [37] "37"  "38"  "39"  "40"  "41"  "42"  "43"  "44"  "45"  "46"  "47"  "48"
+ [49] "49"  "50"  "51"  "52"  "53"  "54"  "55"  "56"  "57"  "58"  "59"  "60"
+ [61] "61"  "62"  "63"  "64"  "65"  "66"  "67"  "68"  "69"  "70"  "71"  "72"
+ [73] "73"  "74"  "75"  "76"  "77"  "78"  "79"  "80"  "81"  "82"  "83"  "84"
+ [85] "85"  "86"  "87"  "88"  "89"  "90"  "91"  "92"  "93"  "94"  "95"  "96"
+ [97] "97"  "98"  "99"  "100"
+
+##com.oracle.truffle.r.test.builtins.TestBuiltin_zzfile.test2#
+#{ f <- tempfile(); c <- bzfile(f); writeLines(as.character(1:50), c); close(c); c <- bzfile(f, "a"); writeLines(as.character(51:70), c); close(c); readLines(f) }
+ [1] "1"  "2"  "3"  "4"  "5"  "6"  "7"  "8"  "9"  "10" "11" "12" "13" "14" "15"
+[16] "16" "17" "18" "19" "20" "21" "22" "23" "24" "25" "26" "27" "28" "29" "30"
+[31] "31" "32" "33" "34" "35" "36" "37" "38" "39" "40" "41" "42" "43" "44" "45"
+[46] "46" "47" "48" "49" "50" "51" "52" "53" "54" "55" "56" "57" "58" "59" "60"
+[61] "61" "62" "63" "64" "65" "66" "67" "68" "69" "70"
+
+##com.oracle.truffle.r.test.builtins.TestBuiltin_zzfile.test2#
+#{ f <- tempfile(); c <- gzfile(f); writeLines(as.character(1:50), c); close(c); c <- gzfile(f, "a"); writeLines(as.character(51:70), c); close(c); readLines(f) }
+ [1] "1"  "2"  "3"  "4"  "5"  "6"  "7"  "8"  "9"  "10" "11" "12" "13" "14" "15"
+[16] "16" "17" "18" "19" "20" "21" "22" "23" "24" "25" "26" "27" "28" "29" "30"
+[31] "31" "32" "33" "34" "35" "36" "37" "38" "39" "40" "41" "42" "43" "44" "45"
+[46] "46" "47" "48" "49" "50" "51" "52" "53" "54" "55" "56" "57" "58" "59" "60"
+[61] "61" "62" "63" "64" "65" "66" "67" "68" "69" "70"
+
+##com.oracle.truffle.r.test.builtins.TestBuiltin_zzfile.test2#
+#{ f <- tempfile(); c <- xzfile(f); writeLines(as.character(1:50), c); close(c); c <- xzfile(f, "a"); writeLines(as.character(51:70), c); close(c); readLines(f) }
+ [1] "1"  "2"  "3"  "4"  "5"  "6"  "7"  "8"  "9"  "10" "11" "12" "13" "14" "15"
+[16] "16" "17" "18" "19" "20" "21" "22" "23" "24" "25" "26" "27" "28" "29" "30"
+[31] "31" "32" "33" "34" "35" "36" "37" "38" "39" "40" "41" "42" "43" "44" "45"
+[46] "46" "47" "48" "49" "50" "51" "52" "53" "54" "55" "56" "57" "58" "59" "60"
+[61] "61" "62" "63" "64" "65" "66" "67" "68" "69" "70"
+
 ##com.oracle.truffle.r.test.builtins.TestMiscBuiltins.testArrayConstructors#
 #{ character(1L) }
 [1] ""
@@ -57534,6 +57747,33 @@ NULL
 #n <- 100; { e <- parent.frame(2); e$n}
 [1] 100
 
+##com.oracle.truffle.r.test.builtins.TestTestBase.testTraits#Output.IgnoreErrorContext#
+#if (exists('.fastr.identity')) { cat('Error in .Internal(foo(44)): IgnoreErrorContext') } else { cat('Error in foo(42): IgnoreErrorContext') }
+Error in foo(42): IgnoreErrorContext
+##com.oracle.truffle.r.test.builtins.TestTestBase.testTraits#Output.IgnoreErrorContext#
+#if (exists('.fastr.identity')) { cat('Error in foo(42)   : IgnoreErrorContext extra spaces') } else { cat('Error in foo(42): IgnoreErrorContext extra spaces') }
+Error in foo(42): IgnoreErrorContext extra spaces
+##com.oracle.truffle.r.test.builtins.TestTestBase.testTraits#Output.IgnoreWhitespace#
+#if (exists('.fastr.identity')) { cat('Error in foo(42) : IgnoreWhitespace extra spaces') } else { cat('Error  in foo(42): \nIgnoreWhitespace extra spaces') }
+Error  in foo(42):
+IgnoreWhitespace extra spaces
+##com.oracle.truffle.r.test.builtins.TestTestBase.testTraits#Output.IgnoreErrorMessage#
+#if (exists('.fastr.identity')) { cat('Error in foo(42): FastR error message') } else { cat('Error in foo(42): GnuR error message is different') }
+Error in foo(42): GnuR error message is different
+##com.oracle.truffle.r.test.builtins.TestTestBase.testTraits#Output.IgnoreErrorMessage#
+#if (exists('.fastr.identity')) { cat('Error in foo(42): IgnoreErrorMessage starts with newline') } else { cat('Error in foo(42):\nIgnoreErrorMessage starts with newline') }
+Error in foo(42):
+IgnoreErrorMessage starts with newline
+##com.oracle.truffle.r.test.builtins.TestTestBase.testTraits#Output.IgnoreErrorMessage#
+#if (exists('.fastr.identity')) { cat('Error in foo(44): IgnoreErrorMessage with different ctx') } else { cat('Error in foo(42): IgnoreErrorMessage with different ctx') }
+Error in foo(42): IgnoreErrorMessage with different ctx
+##com.oracle.truffle.r.test.builtins.TestTestBase.testTraits#Output.IgnoreWarningContext#
+#if (exists('.fastr.identity')) { cat('Warning message: In .Internal(foo(42)) : IgnoreWarningContext extra newline') } else { cat('Warning message: In foo(42) : \nIgnoreWarningContext extra newline') }
+Warning message: In foo(42) :
+IgnoreWarningContext extra newline
+##com.oracle.truffle.r.test.builtins.TestTestBase.testTraits#Output.IgnoreWarningContext#
+#if (exists('.fastr.identity')) { cat('Warning message: In .Internal(foo(42)) : IgnoreWarningContext') } else { cat('Warning message: In foo(42) : IgnoreWarningContext') }
+Warning message: In foo(42) : IgnoreWarningContext
 ##com.oracle.truffle.r.test.functions.TestFunctions.testArgEvaluationOrder#
 #v <- 1; class(v) <- 'foo'; `-.foo` <- function(x,y,...) { cat('[-.foo]'); 1234 }; g <- function(...) { cat('[ing]'); ({cat('[-]'); `-`})(...) }; ({cat('[g]'); g})({cat('[x]'); v},{cat('[y]'); 3},{cat('[z]'); 5})
 [g][ing][-][x][y][z][-.foo][1] 1234
@@ -59129,6 +59369,11 @@ f first 1
 #{f<-function(x){UseMethod("f")};f.logical<-function(x){print("logical")};f(TRUE)}
 [1] "logical"
 
+##com.oracle.truffle.r.test.library.base.TestConditionHandling.testTryCatch#
+#{ e <- simpleError("test error"); f <- function() { tryCatch(1, finally = print("Hello")); stop(e)}; f() }
+[1] "Hello"
+Error: test error
+
 ##com.oracle.truffle.r.test.library.base.TestConditionHandling.testTryCatch#
 #{ e <- simpleError("test error"); tryCatch(stop(e), error = function(e) e, finally = print("Hello"))}
 [1] "Hello"
@@ -59139,6 +59384,14 @@ f first 1
 Error: test error
 [1] "Hello"
 
+##com.oracle.truffle.r.test.library.base.TestConditionHandling.testTryCatch#
+#{ f <- function() { tryCatch(1, error = function(e) print("Hello")); stop("fred")}; f() }
+Error in f() : fred
+
+##com.oracle.truffle.r.test.library.base.TestConditionHandling.testTryCatch#
+#{ f <- function() { tryCatch(stop("fred"), error = function(e) print("Hello"))}; f() }
+[1] "Hello"
+
 ##com.oracle.truffle.r.test.library.base.TestConditionHandling.testTryCatch#
 #{ tryCatch(1, finally = print("Hello")) }
 [1] "Hello"
@@ -111211,6 +111464,16 @@ a b c d e
 #if (length(grep("FastR", R.Version()$version.string)) != 1) { as.character(123) } else { .fastr.interop.eval('application/x-r', 'as.character(123)') }
 [1] "123"
 
+##com.oracle.truffle.r.test.library.fastr.TestInterop.testInteropEvalFile#
+#if (length(grep("FastR", R.Version()$version.string)) != 1) { cat('[1] "Error reading file: /a/b.R"\n') } else { tryCatch(.fastr.interop.evalFile("/a/b.R"),  error = function(e) e$message) }
+[1] "Error reading file: /a/b.R"
+
+##com.oracle.truffle.r.test.library.fastr.TestInterop.testInteropEvalFile#
+#if (length(grep("FastR", R.Version()$version.string)) != 1) { x<-c(1);cat(x) } else { fileConn<-file("testScript.R");writeLines(c("x<-c(1)","cat(x)"), fileConn);close(fileConn);.fastr.interop.evalFile("testScript.R") }
+1
+##com.oracle.truffle.r.test.library.fastr.TestInterop.testInteropEvalFile#
+#if (length(grep("FastR", R.Version()$version.string)) != 1) { x<-c(1);cat(x) } else { fileConn<-file("testScript.R");writeLines(c("x<-c(1)","cat(x)"), fileConn);close(fileConn);.fastr.interop.evalFile("testScript.R","application/x-r") }
+1
 ##com.oracle.truffle.r.test.library.fastr.TestInterop.testInteropExport#
 #if (length(grep("FastR", R.Version()$version.string)) != 1) { invisible() } else { .fastr.interop.export('foo', 'foo') }
 
@@ -111292,6 +111555,3517 @@ attr(,"is.truffle.object")
 #if (length(grep("FastR", R.Version()$version.string)) != 1) { TRUE } else { { x<-rep(1, 100); xi1<-.fastr.identity(x); f<-function(x) { y<-x; y }; f(x); x[1]<-7; xi2<-.fastr.identity(x); xi1 == xi2 } }
 [1] TRUE
 
+##com.oracle.truffle.r.test.library.stats.TestDistributions.testDensityFunctions#Output.MayIgnoreWarningContext#
+#dbeta(0, -1,  0.5)
+[1] NaN
+Warning message:
+In dbeta(0, -1, 0.5) : NaNs produced
+
+##com.oracle.truffle.r.test.library.stats.TestDistributions.testDensityFunctions#Output.MayIgnoreWarningContext#
+#dbeta(0, -4,  15,  0)
+[1] NaN
+Warning message:
+In dbeta(0, -4, 15, 0) : NaNs produced
+
+##com.oracle.truffle.r.test.library.stats.TestDistributions.testDensityFunctions#Output.MayIgnoreWarningContext#
+#dbeta(0, -Inf,  0.5)
+[1] NaN
+Warning message:
+In dbeta(0, -Inf, 0.5) : NaNs produced
+
+##com.oracle.truffle.r.test.library.stats.TestDistributions.testDensityFunctions#Output.MayIgnoreWarningContext#
+#dbeta(0, -Inf,  15,  0)
+[1] NaN
+Warning message:
+In dbeta(0, -Inf, 15, 0) : NaNs produced
+
+##com.oracle.truffle.r.test.library.stats.TestDistributions.testDensityFunctions#Output.MayIgnoreWarningContext#
+#dbeta(0, 0,  0.5)
+[1] Inf
+
+##com.oracle.truffle.r.test.library.stats.TestDistributions.testDensityFunctions#Output.MayIgnoreWarningContext#
+#dbeta(0, 0,  15,  0)
+[1] NaN
+Warning message:
+In dbeta(0, 0, 15, 0) : NaNs produced
+
+##com.oracle.truffle.r.test.library.stats.TestDistributions.testDensityFunctions#Output.MayIgnoreWarningContext#
+#dbeta(0, 0.5, -1)
+[1] NaN
+Warning message:
+In dbeta(0, 0.5, -1) : NaNs produced
+
+##com.oracle.truffle.r.test.library.stats.TestDistributions.testDensityFunctions#Output.MayIgnoreWarningContext#
+#dbeta(0, 0.5, -Inf)
+[1] NaN
+Warning message:
+In dbeta(0, 0.5, -Inf) : NaNs produced
+
+##com.oracle.truffle.r.test.library.stats.TestDistributions.testDensityFunctions#Output.MayIgnoreWarningContext#
+#dbeta(0, 0.5, 0)
+[1] 0
+
+##com.oracle.truffle.r.test.library.stats.TestDistributions.testDensityFunctions#Output.MayIgnoreWarningContext#
+#dbeta(0, 0.5, Inf)
+[1] Inf
+
+##com.oracle.truffle.r.test.library.stats.TestDistributions.testDensityFunctions#Output.MayIgnoreWarningContext#
+#dbeta(0, 0.5, NaN)
+[1] NaN
+
+##com.oracle.truffle.r.test.library.stats.TestDistributions.testDensityFunctions#Output.MayIgnoreWarningContext#
+#dbeta(0, 10,  15, -4)
+[1] NaN
+Warning message:
+In dbeta(0, 10, 15, -4) : NaNs produced
+
+##com.oracle.truffle.r.test.library.stats.TestDistributions.testDensityFunctions#Output.MayIgnoreWarningContext#
+#dbeta(0, 10,  15, -Inf)
+[1] NaN
+Warning message:
+In dbeta(0, 10, 15, -Inf) : NaNs produced
+
+##com.oracle.truffle.r.test.library.stats.TestDistributions.testDensityFunctions#Output.MayIgnoreWarningContext#
+#dbeta(0, 10,  15, 0)
+[1] 0
+
+##com.oracle.truffle.r.test.library.stats.TestDistributions.testDensityFunctions#Output.MayIgnoreWarningContext#
+#dbeta(0, 10,  15, Inf)
+[1] NaN
+Warning message:
+In dbeta(0, 10, 15, Inf) : NaNs produced
+
+##com.oracle.truffle.r.test.library.stats.TestDistributions.testDensityFunctions#Output.MayIgnoreWarningContext#
+#dbeta(0, 10,  15, NaN)
+[1] NaN
+
+##com.oracle.truffle.r.test.library.stats.TestDistributions.testDensityFunctions#Output.MayIgnoreWarningContext#
+#dbeta(0, 10, -4,  0)
+[1] NaN
+Warning message:
+In dbeta(0, 10, -4, 0) : NaNs produced
+
+##com.oracle.truffle.r.test.library.stats.TestDistributions.testDensityFunctions#Output.MayIgnoreWarningContext#
+#dbeta(0, 10, -Inf,  0)
+[1] NaN
+Warning message:
+In dbeta(0, 10, -Inf, 0) : NaNs produced
+
+##com.oracle.truffle.r.test.library.stats.TestDistributions.testDensityFunctions#Output.MayIgnoreWarningContext#
+#dbeta(0, 10, 0,  0)
+[1] NaN
+Warning message:
+In dbeta(0, 10, 0, 0) : NaNs produced
+
+##com.oracle.truffle.r.test.library.stats.TestDistributions.testDensityFunctions#Output.MayIgnoreWarningContext#
+#dbeta(0, 10, Inf,  0)
+[1] NaN
+Warning message:
+In dbeta(0, 10, Inf, 0) : NaNs produced
+
+##com.oracle.truffle.r.test.library.stats.TestDistributions.testDensityFunctions#Output.MayIgnoreWarningContext#
+#dbeta(0, 10, NaN,  0)
+[1] NaN
+
+##com.oracle.truffle.r.test.library.stats.TestDistributions.testDensityFunctions#Output.MayIgnoreWarningContext#
+#dbeta(0, Inf,  0.5)
+[1] 0
+
+##com.oracle.truffle.r.test.library.stats.TestDistributions.testDensityFunctions#Output.MayIgnoreWarningContext#
+#dbeta(0, Inf,  15,  0)
+[1] NaN
+Warning message:
+In dbeta(0, Inf, 15, 0) : NaNs produced
+
+##com.oracle.truffle.r.test.library.stats.TestDistributions.testDensityFunctions#Output.MayIgnoreWarningContext#
+#dbeta(0, NaN,  0.5)
+[1] NaN
+
+##com.oracle.truffle.r.test.library.stats.TestDistributions.testDensityFunctions#Output.MayIgnoreWarningContext#
+#dbeta(0, NaN,  15,  0)
+[1] NaN
+
+##com.oracle.truffle.r.test.library.stats.TestDistributions.testDensityFunctions#Output.MayIgnoreWarningContext#
+#dbeta(c(-Inf, -0.42e-30, 0, 0.42e-30, Inf, NaN), 0.5, 0.5, log=F)
+[1] 0.000000e+00 0.000000e+00          Inf 4.911628e+14 0.000000e+00
+[6]          NaN
+
+##com.oracle.truffle.r.test.library.stats.TestDistributions.testDensityFunctions#Output.MayIgnoreWarningContext#
+#dbeta(c(-Inf, -0.42e-30, 0, 0.42e-30, Inf, NaN), 0.5, 0.5, log=T)
+[1]    -Inf    -Inf     Inf 33.8278    -Inf     NaN
+
+##com.oracle.truffle.r.test.library.stats.TestDistributions.testDensityFunctions#Output.MayIgnoreWarningContext#
+#dbeta(c(0.2, -Inf, -0.42e-30, 0, 0.42e-30, Inf, NaN), 0.1, 3, log=F)
+[1] 3.146552e-01 0.000000e+00 0.000000e+00          Inf 2.521492e+26
+[6] 0.000000e+00          NaN
+
+##com.oracle.truffle.r.test.library.stats.TestDistributions.testDensityFunctions#Output.MayIgnoreWarningContext#
+#dbeta(c(0.2, -Inf, -0.42e-30, 0, 0.42e-30, Inf, NaN), 0.1, 3, log=T)
+[1] -1.156278      -Inf      -Inf       Inf 60.792063      -Inf       NaN
+
+##com.oracle.truffle.r.test.library.stats.TestDistributions.testDensityFunctions#Output.MayIgnoreWarningContext#
+#dbeta(c(0.4, -Inf, -0.42e-30, 0, 0.42e-30, Inf, NaN), 0, 0, log=F)
+[1]   0   0   0 Inf   0   0 NaN
+
+##com.oracle.truffle.r.test.library.stats.TestDistributions.testDensityFunctions#Output.MayIgnoreWarningContext#
+#dbeta(c(0.4, -Inf, -0.42e-30, 0, 0.42e-30, Inf, NaN), 0, 0, log=T)
+[1] -Inf -Inf -Inf  Inf -Inf -Inf  NaN
+
+##com.oracle.truffle.r.test.library.stats.TestDistributions.testDensityFunctions#Output.MayIgnoreWarningContext#
+#dbeta(c(0.5, -Inf, -0.42e-30, 0, 0.42e-30, Inf, NaN), 0, Inf, log=F)
+[1]   0   0   0 Inf   0   0 NaN
+
+##com.oracle.truffle.r.test.library.stats.TestDistributions.testDensityFunctions#Output.MayIgnoreWarningContext#
+#dbeta(c(0.5, -Inf, -0.42e-30, 0, 0.42e-30, Inf, NaN), 0, Inf, log=T)
+[1] -Inf -Inf -Inf  Inf -Inf -Inf  NaN
+
+##com.oracle.truffle.r.test.library.stats.TestDistributions.testDensityFunctions#Output.MayIgnoreWarningContext#
+#dbeta(c(0.5, -Inf, -0.42e-30, 0, 0.42e-30, Inf, NaN), 2, 5, log=F)
+[1] 9.375e-01 0.000e+00 0.000e+00 0.000e+00 1.260e-29 0.000e+00       NaN
+
+##com.oracle.truffle.r.test.library.stats.TestDistributions.testDensityFunctions#Output.MayIgnoreWarningContext#
+#dbeta(c(0.5, -Inf, -0.42e-30, 0, 0.42e-30, Inf, NaN), 2, 5, log=T)
+[1]  -0.06453852         -Inf         -Inf         -Inf -66.54385598
+[6]         -Inf          NaN
+
+##com.oracle.truffle.r.test.library.stats.TestDistributions.testDensityFunctions#Output.MayIgnoreWarningContext#
+#dbeta(c(0.6, -Inf, -0.42e-30, 0, 0.42e-30, Inf, NaN), Inf, 0, log=F)
+[1]   0   0   0   0   0   0 NaN
+
+##com.oracle.truffle.r.test.library.stats.TestDistributions.testDensityFunctions#Output.MayIgnoreWarningContext#
+#dbeta(c(0.6, -Inf, -0.42e-30, 0, 0.42e-30, Inf, NaN), Inf, 0, log=T)
+[1] -Inf -Inf -Inf -Inf -Inf -Inf  NaN
+
+##com.oracle.truffle.r.test.library.stats.TestDistributions.testDensityFunctions#Output.MayIgnoreWarningContext#
+#dbeta(c(0.6, 0.1, 42e-33), 6, 3, log=F)
+[1]  2.090189e+00  1.360800e-03 2.195613e-155
+
+##com.oracle.truffle.r.test.library.stats.TestDistributions.testDensityFunctions#Output.MayIgnoreWarningContext#
+#dbeta(c(0.6, 0.1, 42e-33), 6, 3, log=T)
+[1]    0.7372544   -6.5996825 -356.1142283
+
+##com.oracle.truffle.r.test.library.stats.TestDistributions.testDensityFunctions#Output.MayIgnoreWarningContext#
+#dbeta(c(10, 15, 100), 7, 11, 0.37e-10, log=F)
+[1] 0 0 0
+
+##com.oracle.truffle.r.test.library.stats.TestDistributions.testDensityFunctions#Output.MayIgnoreWarningContext#
+#dbeta(c(10, 15, 100), 7, 11, 0.37e-10, log=T)
+[1] -Inf -Inf -Inf
+
+##com.oracle.truffle.r.test.library.stats.TestDistributions.testDensityFunctions#Output.MayIgnoreWarningContext#
+#dbeta(c(10, 15, 100), 7, 113e11, 1, log=F)
+[1] 0 0 0
+
+##com.oracle.truffle.r.test.library.stats.TestDistributions.testDensityFunctions#Output.MayIgnoreWarningContext#
+#dbeta(c(10, 15, 100), 7, 113e11, 1, log=T)
+[1] -Inf -Inf -Inf
+
+##com.oracle.truffle.r.test.library.stats.TestDistributions.testDensityFunctions#Output.MayIgnoreWarningContext#
+#dbeta(c(10, 15, 100, -Inf, -0.42e-30, 0, 0.42e-30, Inf, NaN), 10, 15, 0, log=F)
+[1]  0.000000e+00  0.000000e+00  0.000000e+00  0.000000e+00  0.000000e+00
+[6]  0.000000e+00 7.975867e-267  0.000000e+00           NaN
+
+##com.oracle.truffle.r.test.library.stats.TestDistributions.testDensityFunctions#Output.MayIgnoreWarningContext#
+#dbeta(c(10, 15, 100, -Inf, -0.42e-30, 0, 0.42e-30, Inf, NaN), 10, 15, 0, log=T)
+[1]      -Inf      -Inf      -Inf      -Inf      -Inf      -Inf -612.7138
+[8]      -Inf       NaN
+
+##com.oracle.truffle.r.test.library.stats.TestDistributions.testDensityFunctions#Output.MayIgnoreWarningContext#
+#dbeta(c(10, 15, 100, -Inf, -0.42e-30, 0, 0.42e-30, Inf, NaN), 7, 13, 3, log=F)
+[1]  0.000000e+00  0.000000e+00  0.000000e+00  0.000000e+00  0.000000e+00
+[6]  0.000000e+00 4.319955e-178  0.000000e+00           NaN
+
+##com.oracle.truffle.r.test.library.stats.TestDistributions.testDensityFunctions#Output.MayIgnoreWarningContext#
+#dbeta(c(10, 15, 100, -Inf, -0.42e-30, 0, 0.42e-30, Inf, NaN), 7, 13, 3, log=T)
+[1]      -Inf      -Inf      -Inf      -Inf      -Inf      -Inf -408.3969
+[8]      -Inf       NaN
+
+##com.oracle.truffle.r.test.library.stats.TestDistributions.testDensityFunctions#Output.MayIgnoreWarningContext#
+#dcauchy(0, -Inf,  -1)
+[1] NaN
+Warning message:
+In dcauchy(0, -Inf, -1) : NaNs produced
+
+##com.oracle.truffle.r.test.library.stats.TestDistributions.testDensityFunctions#Output.MayIgnoreWarningContext#
+#dcauchy(0, 0, -Inf)
+[1] NaN
+Warning message:
+In dcauchy(0, 0, -Inf) : NaNs produced
+
+##com.oracle.truffle.r.test.library.stats.TestDistributions.testDensityFunctions#Output.MayIgnoreWarningContext#
+#dcauchy(0, 0, Inf)
+[1] 0
+
+##com.oracle.truffle.r.test.library.stats.TestDistributions.testDensityFunctions#Output.MayIgnoreWarningContext#
+#dcauchy(0, 0, NaN)
+[1] NaN
+
+##com.oracle.truffle.r.test.library.stats.TestDistributions.testDensityFunctions#Output.MayIgnoreWarningContext#
+#dcauchy(0, Inf,  -1)
+[1] NaN
+Warning message:
+In dcauchy(0, Inf, -1) : NaNs produced
+
+##com.oracle.truffle.r.test.library.stats.TestDistributions.testDensityFunctions#Output.MayIgnoreWarningContext#
+#dcauchy(0, NaN,  -1)
+[1] NaN
+
+##com.oracle.truffle.r.test.library.stats.TestDistributions.testDensityFunctions#Output.MayIgnoreWarningContext#
+#dcauchy(c(-5, 42, -Inf, -0.42e-30, 0, 0.42e-30, Inf, NaN), -5, 5, log=F)
+[1] 0.0636619772 0.0007124214 0.0000000000 0.0318309886 0.0318309886
+[6] 0.0318309886 0.0000000000          NaN
+
+##com.oracle.truffle.r.test.library.stats.TestDistributions.testDensityFunctions#Output.MayIgnoreWarningContext#
+#dcauchy(c(-5, 42, -Inf, -0.42e-30, 0, 0.42e-30, Inf, NaN), -5, 5, log=T)
+[1] -2.754168 -7.246841      -Inf -3.447315 -3.447315 -3.447315      -Inf
+[8]       NaN
+
+##com.oracle.truffle.r.test.library.stats.TestDistributions.testDensityFunctions#Output.MayIgnoreWarningContext#
+#dcauchy(c(0, -1, 1, 0.42e-30), -0.01, 0.03, log=F)
+[1] 9.549296586 0.009734247 0.009352886 9.549296586
+
+##com.oracle.truffle.r.test.library.stats.TestDistributions.testDensityFunctions#Output.MayIgnoreWarningContext#
+#dcauchy(c(0, -1, 1, 0.42e-30), -0.01, 0.03, log=T)
+[1]  2.256467 -4.632105 -4.672070  2.256467
+
+##com.oracle.truffle.r.test.library.stats.TestDistributions.testDensityFunctions#Output.MayIgnoreWarningContext#
+#dcauchy(c(0, -1, 42), 0, -1, log=F)
+[1] NaN NaN NaN
+Warning message:
+In dcauchy(c(0, -1, 42), 0, -1, log = F) : NaNs produced
+
+##com.oracle.truffle.r.test.library.stats.TestDistributions.testDensityFunctions#Output.MayIgnoreWarningContext#
+#dcauchy(c(0, -1, 42), 0, -1, log=T)
+[1] NaN NaN NaN
+Warning message:
+In dcauchy(c(0, -1, 42), 0, -1, log = T) : NaNs produced
+
+##com.oracle.truffle.r.test.library.stats.TestDistributions.testDensityFunctions#Output.MayIgnoreWarningContext#
+#dchisq(0, -3,  1)
+[1] NaN
+Warning message:
+In dchisq(0, -3, 1) : NaNs produced
+
+##com.oracle.truffle.r.test.library.stats.TestDistributions.testDensityFunctions#Output.MayIgnoreWarningContext#
+#dchisq(0, -Inf,  1)
+[1] NaN
+Warning message:
+In dchisq(0, -Inf, 1) : NaNs produced
+
+##com.oracle.truffle.r.test.library.stats.TestDistributions.testDensityFunctions#Output.MayIgnoreWarningContext#
+#dchisq(0, 0,  1)
+[1] Inf
+
+##com.oracle.truffle.r.test.library.stats.TestDistributions.testDensityFunctions#Output.MayIgnoreWarningContext#
+#dchisq(0, 1, -3)
+[1] NaN
+Warning message:
+In dchisq(0, 1, -3) : NaNs produced
+
+##com.oracle.truffle.r.test.library.stats.TestDistributions.testDensityFunctions#Output.MayIgnoreWarningContext#
+#dchisq(0, 1, -Inf)
+[1] NaN
+Warning message:
+In dchisq(0, 1, -Inf) : NaNs produced
+
+##com.oracle.truffle.r.test.library.stats.TestDistributions.testDensityFunctions#Output.MayIgnoreWarningContext#
+#dchisq(0, 1, 0)
+[1] Inf
+
+##com.oracle.truffle.r.test.library.stats.TestDistributions.testDensityFunctions#Output.MayIgnoreWarningContext#
+#dchisq(0, 1, Inf)
+[1] NaN
+Warning message:
+In dchisq(0, 1, Inf) : NaNs produced
+
+##com.oracle.truffle.r.test.library.stats.TestDistributions.testDensityFunctions#Output.MayIgnoreWarningContext#
+#dchisq(0, 1, NaN)
+[1] NaN
+
+##com.oracle.truffle.r.test.library.stats.TestDistributions.testDensityFunctions#Output.MayIgnoreWarningContext#
+#dchisq(0, Inf,  1)
+[1] NaN
+Warning message:
+In dchisq(0, Inf, 1) : NaNs produced
+
+##com.oracle.truffle.r.test.library.stats.TestDistributions.testDensityFunctions#Output.MayIgnoreWarningContext#
+#dchisq(0, NaN,  1)
+[1] NaN
+
+##com.oracle.truffle.r.test.library.stats.TestDistributions.testDensityFunctions#Output.MayIgnoreWarningContext#
+#dchisq(c(0.42e-10, 100, 13e10, 11e111), 0.13e-8, 1, log=F)
+[1] 9.538417e+00 1.370516e-20 0.000000e+00 0.000000e+00
+
+##com.oracle.truffle.r.test.library.stats.TestDistributions.testDensityFunctions#Output.MayIgnoreWarningContext#
+#dchisq(c(0.42e-10, 100, 13e10, 11e111), 0.13e-8, 1, log=T)
+[1]   2.255327e+00  -4.573651e+01  -3.250000e+10 -2.750000e+111
+
+##com.oracle.truffle.r.test.library.stats.TestDistributions.testDensityFunctions#Output.MayIgnoreWarningContext#
+#dchisq(c(0.42e-10, 100, 13e10, 11e111), 1, 0.13e-8, log=F)
+[1] 6.155813e+04 7.694599e-24 0.000000e+00 0.000000e+00
+
+##com.oracle.truffle.r.test.library.stats.TestDistributions.testDensityFunctions#Output.MayIgnoreWarningContext#
+#dchisq(c(0.42e-10, 100, 13e10, 11e111), 1, 0.13e-8, log=T)
+[1]   1.102774e+01  -5.322152e+01  -6.500000e+10 -5.500000e+111
+
+##com.oracle.truffle.r.test.library.stats.TestDistributions.testDensityFunctions#Output.MayIgnoreWarningContext#
+#dchisq(c(0.42e-10, 100, 13e10, 11e111), 420, 4, log=F)
+[1] 0.000000e+00 5.065225e-64 0.000000e+00 0.000000e+00
+
+##com.oracle.truffle.r.test.library.stats.TestDistributions.testDensityFunctions#Output.MayIgnoreWarningContext#
+#dchisq(c(0.42e-10, 100, 13e10, 11e111), 420, 4, log=T)
+[1]  -6.052932e+03  -1.457430e+02  -6.439252e+10 -5.448598e+111
+
+##com.oracle.truffle.r.test.library.stats.TestDistributions.testDensityFunctions#Output.MayIgnoreWarningContext#
+#dchisq(c(0.5, 2, -Inf, -0.42e-30, 0, 0.42e-30, Inf, NaN), 1, 1, log=F)
+[1] 3.359531e-01 1.371033e-01 0.000000e+00 0.000000e+00          Inf
+[6] 3.733689e+14 0.000000e+00          NaN
+
+##com.oracle.truffle.r.test.library.stats.TestDistributions.testDensityFunctions#Output.MayIgnoreWarningContext#
+#dchisq(c(0.5, 2, -Inf, -0.42e-30, 0, 0.42e-30, Inf, NaN), 1, 1, log=T)
+[1] -1.090784 -1.987021      -Inf      -Inf       Inf 33.553588      -Inf
+[8]       NaN
+
+##com.oracle.truffle.r.test.library.stats.TestDistributions.testDensityFunctions#Output.MayIgnoreWarningContext#
+#dexp(0, -1)
+[1] NaN
+Warning message:
+In dexp(0, -1) : NaNs produced
+
+##com.oracle.truffle.r.test.library.stats.TestDistributions.testDensityFunctions#Output.MayIgnoreWarningContext#
+#dexp(0, -Inf)
+[1] NaN
+Warning message:
+In dexp(0, -Inf) : NaNs produced
+
+##com.oracle.truffle.r.test.library.stats.TestDistributions.testDensityFunctions#Output.MayIgnoreWarningContext#
+#dexp(0, 0)
+[1] 0
+
+##com.oracle.truffle.r.test.library.stats.TestDistributions.testDensityFunctions#Output.MayIgnoreWarningContext#
+#dexp(0, Inf)
+[1] NaN
+Warning message:
+In dexp(0, Inf) : NaNs produced
+
+##com.oracle.truffle.r.test.library.stats.TestDistributions.testDensityFunctions#Output.MayIgnoreWarningContext#
+#dexp(0, NaN)
+[1] NaN
+
+##com.oracle.truffle.r.test.library.stats.TestDistributions.testDensityFunctions#Output.MayIgnoreWarningContext#
+#dexp(c(10, -10, -Inf, -0.42e-30, 0, 0.42e-30, Inf, NaN), 13e-20, log=F)
+[1] 1.3e-19 0.0e+00 0.0e+00 0.0e+00 1.3e-19 1.3e-19 0.0e+00     NaN
+
+##com.oracle.truffle.r.test.library.stats.TestDistributions.testDensityFunctions#Output.MayIgnoreWarningContext#
+#dexp(c(10, -10, -Inf, -0.42e-30, 0, 0.42e-30, Inf, NaN), 13e-20, log=T)
+[1] -43.48675      -Inf      -Inf      -Inf -43.48675 -43.48675      -Inf
+[8]       NaN
+
+##com.oracle.truffle.r.test.library.stats.TestDistributions.testDensityFunctions#Output.MayIgnoreWarningContext#
+#dexp(c(33e123, -Inf, -0.42e-30, 0, 0.42e-30, Inf, NaN), 42e123, log=F)
+[1]  0.0e+00  0.0e+00  0.0e+00 4.2e+124  0.0e+00  0.0e+00      NaN
+
+##com.oracle.truffle.r.test.library.stats.TestDistributions.testDensityFunctions#Output.MayIgnoreWarningContext#
+#dexp(c(33e123, -Inf, -0.42e-30, 0, 0.42e-30, Inf, NaN), 42e123, log=T)
+[1] -1.386000e+249           -Inf           -Inf   2.869556e+02  -1.764000e+94
+[6]           -Inf            NaN
+
+##com.oracle.truffle.r.test.library.stats.TestDistributions.testDensityFunctions#Output.MayIgnoreWarningContext#
+#dexp(c(42, -Inf, -0.42e-30, 0, 0.42e-30, Inf, NaN), 42, log=F)
+[1]   0   0   0  42  42   0 NaN
+
+##com.oracle.truffle.r.test.library.stats.TestDistributions.testDensityFunctions#Output.MayIgnoreWarningContext#
+#dexp(c(42, -Inf, -0.42e-30, 0, 0.42e-30, Inf, NaN), 42, log=T)
+[1] -1760.26233        -Inf        -Inf     3.73767     3.73767        -Inf
+[7]         NaN
+
+##com.oracle.truffle.r.test.library.stats.TestDistributions.testDensityFunctions#Output.MayIgnoreWarningContext#
+#df(0, -1,  5,  5)
+[1] NaN
+Warning message:
+In df(0, -1, 5, 5) : NaNs produced
+
+##com.oracle.truffle.r.test.library.stats.TestDistributions.testDensityFunctions#Output.MayIgnoreWarningContext#
+#df(0, -Inf,  5,  5)
+[1] NaN
+Warning message:
+In df(0, -Inf, 5, 5) : NaNs produced
+
+##com.oracle.truffle.r.test.library.stats.TestDistributions.testDensityFunctions#Output.MayIgnoreWarningContext#
+#df(0, 0,  5,  5)
+[1] NaN
+Warning message:
+In df(0, 0, 5, 5) : NaNs produced
+
+##com.oracle.truffle.r.test.library.stats.TestDistributions.testDensityFunctions#Output.MayIgnoreWarningContext#
+#df(0, 5,  5, -1)
+[1] NaN
+Warning message:
+In df(0, 5, 5, -1) : NaNs produced
+
+##com.oracle.truffle.r.test.library.stats.TestDistributions.testDensityFunctions#Output.MayIgnoreWarningContext#
+#df(0, 5,  5, -Inf)
+[1] NaN
+Warning message:
+In df(0, 5, 5, -Inf) : NaNs produced
+
+##com.oracle.truffle.r.test.library.stats.TestDistributions.testDensityFunctions#Output.MayIgnoreWarningContext#
+#df(0, 5,  5, 0)
+[1] 0
+
+##com.oracle.truffle.r.test.library.stats.TestDistributions.testDensityFunctions#Output.MayIgnoreWarningContext#
+#df(0, 5,  5, Inf)
+[1] NaN
+Warning message:
+In df(0, 5, 5, Inf) : NaNs produced
+
+##com.oracle.truffle.r.test.library.stats.TestDistributions.testDensityFunctions#Output.MayIgnoreWarningContext#
+#df(0, 5,  5, NaN)
+[1] NaN
+
+##com.oracle.truffle.r.test.library.stats.TestDistributions.testDensityFunctions#Output.MayIgnoreWarningContext#
+#df(0, 5, -1,  5)
+[1] NaN
+Warning message:
+In df(0, 5, -1, 5) : NaNs produced
+
+##com.oracle.truffle.r.test.library.stats.TestDistributions.testDensityFunctions#Output.MayIgnoreWarningContext#
+#df(0, 5, -Inf,  5)
+[1] NaN
+Warning message:
+In df(0, 5, -Inf, 5) : NaNs produced
+
+##com.oracle.truffle.r.test.library.stats.TestDistributions.testDensityFunctions#Output.MayIgnoreWarningContext#
+#df(0, 5, 0,  5)
+[1] NaN
+Warning message:
+In df(0, 5, 0, 5) : NaNs produced
+
+##com.oracle.truffle.r.test.library.stats.TestDistributions.testDensityFunctions#Output.MayIgnoreWarningContext#
+#df(0, 5, Inf,  5)
+[1] 0
+
+##com.oracle.truffle.r.test.library.stats.TestDistributions.testDensityFunctions#Output.MayIgnoreWarningContext#
+#df(0, 5, NaN,  5)
+[1] NaN
+
+##com.oracle.truffle.r.test.library.stats.TestDistributions.testDensityFunctions#Output.MayIgnoreWarningContext#
+#df(0, Inf,  5,  5)
+[1] NaN
+Warning message:
+In df(0, Inf, 5, 5) : NaNs produced
+
+##com.oracle.truffle.r.test.library.stats.TestDistributions.testDensityFunctions#Output.MayIgnoreWarningContext#
+#df(0, NaN,  5,  5)
+[1] NaN
+
+##com.oracle.truffle.r.test.library.stats.TestDistributions.testDensityFunctions#Output.MayIgnoreWarningContext#
+#df(c(1, 10, 44, 123, -Inf, -0.42e-30, 0, 0.42e-30, Inf, NaN), 0.12e-10, 6, 31e10, log=F)
+ [1]   0   0   0   0   0   0 Inf   0 NaN NaN
+Warning message:
+In df(c(1, 10, 44, 123, -Inf, -4.2e-31, 0, 4.2e-31, Inf, NaN), 1.2e-11,  :
+  NaNs produced
+
+##com.oracle.truffle.r.test.library.stats.TestDistributions.testDensityFunctions#Output.MayIgnoreWarningContext#
+#df(c(1, 10, 44, 123, -Inf, -0.42e-30, 0, 0.42e-30, Inf, NaN), 0.12e-10, 6, 31e10, log=T)
+ [1] -1.55e+11 -1.55e+11 -1.55e+11 -1.55e+11      -Inf      -Inf       Inf
+ [8] -1.55e+11       NaN       NaN
+Warning message:
+In df(c(1, 10, 44, 123, -Inf, -4.2e-31, 0, 4.2e-31, Inf, NaN), 1.2e-11,  :
+  NaNs produced
+
+##com.oracle.truffle.r.test.library.stats.TestDistributions.testDensityFunctions#Output.MayIgnoreWarningContext#
+#df(c(1, 10, 44, 123, -Inf, -0.42e-30, 0, 0.42e-30, Inf, NaN), 5, 0.12e-10, 5, log=F)
+ [1] 6.000077e-12 5.999245e-13 1.364474e-13 4.871126e-14 0.000000e+00
+ [6] 0.000000e+00 0.000000e+00 1.502315e-29          NaN          NaN
+Warning message:
+In df(c(1, 10, 44, 123, -Inf, -4.2e-31, 0, 4.2e-31, Inf, NaN), 5,  :
+  NaNs produced
+
+##com.oracle.truffle.r.test.library.stats.TestDistributions.testDensityFunctions#Output.MayIgnoreWarningContext#
+#df(c(1, 10, 44, 123, -Inf, -0.42e-30, 0, 0.42e-30, Inf, NaN), 5, 0.12e-10, 5, log=T)
+ [1] -25.83925 -28.14197 -29.62284 -30.65287      -Inf      -Inf      -Inf
+ [8] -66.36796       NaN       NaN
+Warning message:
+In df(c(1, 10, 44, 123, -Inf, -4.2e-31, 0, 4.2e-31, Inf, NaN), 5,  :
+  NaNs produced
+
+##com.oracle.truffle.r.test.library.stats.TestDistributions.testDensityFunctions#Output.MayIgnoreWarningContext#
+#df(c(1, 10, 44, 123, -Inf, -0.42e-30, 0, 0.42e-30, Inf, NaN), 5, 5, 5, log=F)
+ [1] 3.161392e-01 9.493410e-03 9.824795e-05 3.042534e-06 0.000000e+00
+ [6] 0.000000e+00 0.000000e+00 3.034426e-46          NaN          NaN
+Warning message:
+In df(c(1, 10, 44, 123, -Inf, -4.2e-31, 0, 4.2e-31, Inf, NaN), 5,  :
+  NaNs produced
+
+##com.oracle.truffle.r.test.library.stats.TestDistributions.testDensityFunctions#Output.MayIgnoreWarningContext#
+#df(c(1, 10, 44, 123, -Inf, -0.42e-30, 0, 0.42e-30, Inf, NaN), 5, 5, 5, log=T)
+ [1]   -1.151573   -4.657157   -9.228016  -12.702820        -Inf        -Inf
+ [7]        -Inf -104.808892         NaN         NaN
+Warning message:
+In df(c(1, 10, 44, 123, -Inf, -4.2e-31, 0, 4.2e-31, Inf, NaN), 5,  :
+  NaNs produced
+
+##com.oracle.truffle.r.test.library.stats.TestDistributions.testDensityFunctions#Output.MayIgnoreWarningContext#
+#df(c(1, 10, 44, 123, -Inf, -0.42e-30, 0, 0.42e-30, Inf, NaN), 5, 6, 0.12e-10, log=F)
+ [1] 4.450508e-01 1.824043e-03 7.828020e-06 1.409040e-07 0.000000e+00
+ [6] 0.000000e+00 0.000000e+00 3.397124e-45          NaN          NaN
+Warning message:
+In df(c(1, 10, 44, 123, -Inf, -4.2e-31, 0, 4.2e-31, Inf, NaN), 5,  :
+  NaNs produced
+
+##com.oracle.truffle.r.test.library.stats.TestDistributions.testDensityFunctions#Output.MayIgnoreWarningContext#
+#df(c(1, 10, 44, 123, -Inf, -0.42e-30, 0, 0.42e-30, Inf, NaN), 5, 6, 0.12e-10, log=T)
+ [1]   -0.8095669   -6.3066996  -11.7578009  -15.7751873         -Inf
+ [6]         -Inf         -Inf -102.3934000          NaN          NaN
+Warning message:
+In df(c(1, 10, 44, 123, -Inf, -4.2e-31, 0, 4.2e-31, Inf, NaN), 5,  :
+  NaNs produced
+
+##com.oracle.truffle.r.test.library.stats.TestDistributions.testDensityFunctions#Output.MayIgnoreWarningContext#
+#dgamma(0, -1,  scale=2)
+[1] NaN
+Warning message:
+In dgamma(0, -1, scale = 2) : NaNs produced
+
+##com.oracle.truffle.r.test.library.stats.TestDistributions.testDensityFunctions#Output.MayIgnoreWarningContext#
+#dgamma(0, -Inf,  scale=2)
+[1] NaN
+Warning message:
+In dgamma(0, -Inf, scale = 2) : NaNs produced
+
+##com.oracle.truffle.r.test.library.stats.TestDistributions.testDensityFunctions#Output.MayIgnoreWarningContext#
+#dgamma(0, 0,  scale=2)
+[1] Inf
+
+##com.oracle.truffle.r.test.library.stats.TestDistributions.testDensityFunctions#Output.MayIgnoreWarningContext#
+#dgamma(0, 1, -1)
+[1] NaN
+Warning message:
+In dgamma(0, 1, -1) : NaNs produced
+
+##com.oracle.truffle.r.test.library.stats.TestDistributions.testDensityFunctions#Output.MayIgnoreWarningContext#
+#dgamma(0, 1, -Inf)
+[1] NaN
+Warning message:
+In dgamma(0, 1, -Inf) : NaNs produced
+
+##com.oracle.truffle.r.test.library.stats.TestDistributions.testDensityFunctions#Output.MayIgnoreWarningContext#
+#dgamma(0, 1, 0)
+[1] 0
+
+##com.oracle.truffle.r.test.library.stats.TestDistributions.testDensityFunctions#Output.MayIgnoreWarningContext#
+#dgamma(0, 1, Inf)
+[1] NaN
+Warning message:
+In dgamma(0, 1, Inf) : NaNs produced
+
+##com.oracle.truffle.r.test.library.stats.TestDistributions.testDensityFunctions#Output.MayIgnoreWarningContext#
+#dgamma(0, 1, NaN)
+[1] NaN
+
+##com.oracle.truffle.r.test.library.stats.TestDistributions.testDensityFunctions#Output.MayIgnoreWarningContext#
+#dgamma(0, Inf,  scale=2)
+[1] 0
+
+##com.oracle.truffle.r.test.library.stats.TestDistributions.testDensityFunctions#Output.MayIgnoreWarningContext#
+#dgamma(0, NaN,  scale=2)
+[1] NaN
+
+##com.oracle.truffle.r.test.library.stats.TestDistributions.testDensityFunctions#Output.MayIgnoreWarningContext#
+#dgamma(c(-Inf, -0.42e-30, 0, 0.42e-30, Inf, NaN), 1, scale=2, log=F)
+[1] 0.0 0.0 0.5 0.5 0.0 NaN
+
+##com.oracle.truffle.r.test.library.stats.TestDistributions.testDensityFunctions#Output.MayIgnoreWarningContext#
+#dgamma(c(-Inf, -0.42e-30, 0, 0.42e-30, Inf, NaN), 1, scale=2, log=T)
+[1]       -Inf       -Inf -0.6931472 -0.6931472       -Inf        NaN
+
+##com.oracle.truffle.r.test.library.stats.TestDistributions.testDensityFunctions#Output.MayIgnoreWarningContext#
+#dgamma(c(900, 5000, 0), 11e11, scale=23e-11, log=F)
+[1] 0 0 0
+
+##com.oracle.truffle.r.test.library.stats.TestDistributions.testDensityFunctions#Output.MayIgnoreWarningContext#
+#dgamma(c(900, 5000, 0), 11e11, scale=23e-11, log=T)
+[1] -1.417138e+12 -1.735695e+13          -Inf
+
+##com.oracle.truffle.r.test.library.stats.TestDistributions.testDensityFunctions#Output.MayIgnoreWarningContext#
+#dhyper(0, -10,  11,  4)
+[1] NaN
+Warning message:
+In dhyper(0, -10, 11, 4) : NaNs produced
+
+##com.oracle.truffle.r.test.library.stats.TestDistributions.testDensityFunctions#Output.MayIgnoreWarningContext#
+#dhyper(0, -Inf,  11,  4)
+[1] NaN
+Warning message:
+In dhyper(0, -Inf, 11, 4) : NaNs produced
+
+##com.oracle.truffle.r.test.library.stats.TestDistributions.testDensityFunctions#Output.MayIgnoreWarningContext#
+#dhyper(0, 0.3,  11,  4)
+[1] NaN
+Warning message:
+In dhyper(0, 0.3, 11, 4) : NaNs produced
+
+##com.oracle.truffle.r.test.library.stats.TestDistributions.testDensityFunctions#Output.MayIgnoreWarningContext#
+#dhyper(0, 7,  11, -10)
+[1] NaN
+Warning message:
+In dhyper(0, 7, 11, -10) : NaNs produced
+
+##com.oracle.truffle.r.test.library.stats.TestDistributions.testDensityFunctions#Output.MayIgnoreWarningContext#
+#dhyper(0, 7,  11, -Inf)
+[1] NaN
+Warning message:
+In dhyper(0, 7, 11, -Inf) : NaNs produced
+
+##com.oracle.truffle.r.test.library.stats.TestDistributions.testDensityFunctions#Output.MayIgnoreWarningContext#
+#dhyper(0, 7,  11, 0.3)
+[1] NaN
+Warning message:
+In dhyper(0, 7, 11, 0.3) : NaNs produced
+
+##com.oracle.truffle.r.test.library.stats.TestDistributions.testDensityFunctions#Output.MayIgnoreWarningContext#
+#dhyper(0, 7,  11, Inf)
+[1] NaN
+Warning message:
+In dhyper(0, 7, 11, Inf) : NaNs produced
+
+##com.oracle.truffle.r.test.library.stats.TestDistributions.testDensityFunctions#Output.MayIgnoreWarningContext#
+#dhyper(0, 7,  11, NaN)
+[1] NaN
+
+##com.oracle.truffle.r.test.library.stats.TestDistributions.testDensityFunctions#Output.MayIgnoreWarningContext#
+#dhyper(0, 7, -10,  4)
+[1] NaN
+Warning message:
+In dhyper(0, 7, -10, 4) : NaNs produced
+
+##com.oracle.truffle.r.test.library.stats.TestDistributions.testDensityFunctions#Output.MayIgnoreWarningContext#
+#dhyper(0, 7, -Inf,  4)
+[1] NaN
+Warning message:
+In dhyper(0, 7, -Inf, 4) : NaNs produced
+
+##com.oracle.truffle.r.test.library.stats.TestDistributions.testDensityFunctions#Output.MayIgnoreWarningContext#
+#dhyper(0, 7, 0.3,  4)
+[1] NaN
+Warning message:
+In dhyper(0, 7, 0.3, 4) : NaNs produced
+
+##com.oracle.truffle.r.test.library.stats.TestDistributions.testDensityFunctions#Output.MayIgnoreWarningContext#
+#dhyper(0, 7, Inf,  4)
+[1] NaN
+Warning message:
+In dhyper(0, 7, Inf, 4) : NaNs produced
+
+##com.oracle.truffle.r.test.library.stats.TestDistributions.testDensityFunctions#Output.MayIgnoreWarningContext#
+#dhyper(0, 7, NaN,  4)
+[1] NaN
+
+##com.oracle.truffle.r.test.library.stats.TestDistributions.testDensityFunctions#Output.MayIgnoreWarningContext#
+#dhyper(0, Inf,  11,  4)
+[1] NaN
+Warning message:
+In dhyper(0, Inf, 11, 4) : NaNs produced
+
+##com.oracle.truffle.r.test.library.stats.TestDistributions.testDensityFunctions#Output.MayIgnoreWarningContext#
+#dhyper(0, NaN,  11,  4)
+[1] NaN
+
+##com.oracle.truffle.r.test.library.stats.TestDistributions.testDensityFunctions#Output.MayIgnoreWarningContext#
+#dhyper(c(0.1, -Inf, Inf, 0.3e89), 5, 5, 5, log=F)
+[1] 0 0 0 0
+Warning message:
+In dhyper(c(0.1, -Inf, Inf, 3e+88), 5, 5, 5, log = F) :
+  non-integer x = 0.100000
+
+##com.oracle.truffle.r.test.library.stats.TestDistributions.testDensityFunctions#Output.MayIgnoreWarningContext#
+#dhyper(c(0.1, -Inf, Inf, 0.3e89), 5, 5, 5, log=T)
+[1] -Inf -Inf -Inf -Inf
+Warning message:
+In dhyper(c(0.1, -Inf, Inf, 3e+88), 5, 5, 5, log = T) :
+  non-integer x = 0.100000
+
+##com.oracle.truffle.r.test.library.stats.TestDistributions.testDensityFunctions#Output.MayIgnoreWarningContext#
+#dhyper(c(1, 2, 3, 4, 20, 12e12), 7, 11, 4, log=F)
+[1] 0.37745098 0.37745098 0.12581699 0.01143791 0.00000000 0.00000000
+
+##com.oracle.truffle.r.test.library.stats.TestDistributions.testDensityFunctions#Output.MayIgnoreWarningContext#
+#dhyper(c(1, 2, 3, 4, 20, 12e12), 7, 11, 4, log=T)
+[1] -0.9743146 -0.9743146 -2.0729269 -4.4708221       -Inf       -Inf
+
+##com.oracle.truffle.r.test.library.stats.TestDistributions.testDensityFunctions#Output.MayIgnoreWarningContext#
+#dhyper(c(1, 2, 3, 4, 20, 12e12), 7e12, 11, 4, log=F)
+[1] 1.154519e-35 1.346939e-23 6.285714e-12 1.000000e+00 0.000000e+00
+[6] 0.000000e+00
+
+##com.oracle.truffle.r.test.library.stats.TestDistributions.testDensityFunctions#Output.MayIgnoreWarningContext#
+#dhyper(c(1, 2, 3, 4, 20, 12e12), 7e12, 11, 4, log=T)
+[1] -8.044679e+01 -5.266162e+01 -2.579274e+01 -6.285639e-12          -Inf
+[6]          -Inf
+
+##com.oracle.truffle.r.test.library.stats.TestDistributions.testDensityFunctions#Output.MayIgnoreWarningContext#
+#dhyper(c(1, 2, 3, 4, 5, 6, 7, 8, 11, 20, 12e12), 7, 11, 12, log=F)
+ [1] 0.0003770739 0.0124434389 0.1036953243 0.3110859729 0.3733031674
+ [6] 0.1742081448 0.0248868778 0.0000000000 0.0000000000 0.0000000000
+[11] 0.0000000000
+
+##com.oracle.truffle.r.test.library.stats.TestDistributions.testDensityFunctions#Output.MayIgnoreWarningContext#
+#dhyper(c(1, 2, 3, 4, 5, 6, 7, 8, 11, 20, 12e12), 7, 11, 12, log=T)
+ [1] -7.8830694 -4.3865618 -2.2662983 -1.1676860 -0.9853644 -1.7475045
+ [7] -3.6934146       -Inf       -Inf       -Inf       -Inf
+
+##com.oracle.truffle.r.test.library.stats.TestDistributions.testDensityFunctions#Output.MayIgnoreWarningContext#
+#dhyper(c(1, 2, 3, 7, 20, 12e12), 11, 7e12, 7, log=F)
+[1] 1.100000e-11 4.714286e-23 1.010204e-34 2.019567e-84 0.000000e+00
+[6] 0.000000e+00
+
+##com.oracle.truffle.r.test.library.stats.TestDistributions.testDensityFunctions#Output.MayIgnoreWarningContext#
+#dhyper(c(1, 2, 3, 7, 20, 12e12), 11, 7e12, 7, log=T)
+[1]  -25.23313  -51.40886  -78.27774 -192.71426       -Inf       -Inf
+
+##com.oracle.truffle.r.test.library.stats.TestDistributions.testDensityFunctions#Output.MayIgnoreWarningContext#
+#dhyper(c(2), 3, 4, 10, log=F)
+[1] NaN
+Warning message:
+In dhyper(c(2), 3, 4, 10, log = F) : NaNs produced
+
+##com.oracle.truffle.r.test.library.stats.TestDistributions.testDensityFunctions#Output.MayIgnoreWarningContext#
+#dhyper(c(2), 3, 4, 10, log=T)
+[1] NaN
+Warning message:
+In dhyper(c(2), 3, 4, 10, log = T) : NaNs produced
+
+##com.oracle.truffle.r.test.library.stats.TestDistributions.testDensityFunctions#Output.MayIgnoreWarningContext#
+#dnorm(0, -Inf,  -1)
+[1] NaN
+Warning message:
+In dnorm(0, -Inf, -1) : NaNs produced
+
+##com.oracle.truffle.r.test.library.stats.TestDistributions.testDensityFunctions#Output.MayIgnoreWarningContext#
+#dnorm(0, 0, -Inf)
+[1] 0
+
+##com.oracle.truffle.r.test.library.stats.TestDistributions.testDensityFunctions#Output.MayIgnoreWarningContext#
+#dnorm(0, 0, Inf)
+[1] 0
+
+##com.oracle.truffle.r.test.library.stats.TestDistributions.testDensityFunctions#Output.MayIgnoreWarningContext#
+#dnorm(0, 0, NaN)
+[1] NaN
+
+##com.oracle.truffle.r.test.library.stats.TestDistributions.testDensityFunctions#Output.MayIgnoreWarningContext#
+#dnorm(0, Inf,  -1)
+[1] NaN
+Warning message:
+In dnorm(0, Inf, -1) : NaNs produced
+
+##com.oracle.truffle.r.test.library.stats.TestDistributions.testDensityFunctions#Output.MayIgnoreWarningContext#
+#dnorm(0, NaN,  -1)
+[1] NaN
+
+##com.oracle.truffle.r.test.library.stats.TestDistributions.testDensityFunctions#Output.MayIgnoreWarningContext#
+#dnorm(c(0), 0, -1, log=F)
+[1] NaN
+Warning message:
+In dnorm(c(0), 0, -1, log = F) : NaNs produced
+
+##com.oracle.truffle.r.test.library.stats.TestDistributions.testDensityFunctions#Output.MayIgnoreWarningContext#
+#dnorm(c(0), 0, -1, log=T)
+[1] NaN
+Warning message:
+In dnorm(c(0), 0, -1, log = T) : NaNs produced
+
+##com.oracle.truffle.r.test.library.stats.TestDistributions.testDensityFunctions#Output.MayIgnoreWarningContext#
+#dnorm(c(1, -Inf, -0.42e-30, 0, 0.42e-30, Inf, NaN), 0, 0, log=F)
+[1]   0   0   0 Inf   0   0 NaN
+
+##com.oracle.truffle.r.test.library.stats.TestDistributions.testDensityFunctions#Output.MayIgnoreWarningContext#
+#dnorm(c(1, -Inf, -0.42e-30, 0, 0.42e-30, Inf, NaN), 0, 0, log=T)
+[1] -Inf -Inf -Inf  Inf -Inf -Inf  NaN
+
+##com.oracle.truffle.r.test.library.stats.TestDistributions.testDensityFunctions#Output.MayIgnoreWarningContext#
+#dnorm(c(4, -100, 0), 4, 4, log=F)
+[1]  9.973557e-02 1.611815e-148  6.049268e-02
+
+##com.oracle.truffle.r.test.library.stats.TestDistributions.testDensityFunctions#Output.MayIgnoreWarningContext#
+#dnorm(c(4, -100, 0), 4, 4, log=T)
+[1]   -2.305233 -340.305233   -2.805233
+
+##com.oracle.truffle.r.test.library.stats.TestDistributions.testDensityFunctions#Output.MayIgnoreWarningContext#
+#dunif(0, -3, -Inf)
+[1] NaN
+Warning message:
+In dunif(0, -3, -Inf) : NaNs produced
+
+##com.oracle.truffle.r.test.library.stats.TestDistributions.testDensityFunctions#Output.MayIgnoreWarningContext#
+#dunif(0, -3, Inf)
+[1] 0
+
+##com.oracle.truffle.r.test.library.stats.TestDistributions.testDensityFunctions#Output.MayIgnoreWarningContext#
+#dunif(0, -3, NaN)
+[1] NaN
+
+##com.oracle.truffle.r.test.library.stats.TestDistributions.testDensityFunctions#Output.MayIgnoreWarningContext#
+#dunif(0, -Inf,  3.3)
+[1] 0
+
+##com.oracle.truffle.r.test.library.stats.TestDistributions.testDensityFunctions#Output.MayIgnoreWarningContext#
+#dunif(0, Inf,  3.3)
+[1] NaN
+Warning message:
+In dunif(0, Inf, 3.3) : NaNs produced
+
+##com.oracle.truffle.r.test.library.stats.TestDistributions.testDensityFunctions#Output.MayIgnoreWarningContext#
+#dunif(0, NaN,  3.3)
+[1] NaN
+
+##com.oracle.truffle.r.test.library.stats.TestDistributions.testDensityFunctions#Output.MayIgnoreWarningContext#
+#dunif(c(-3, 2, 3.3, -Inf, -0.42e-30, 0, 0.42e-30, Inf, NaN), -3, 3.3, log=F)
+[1] 0.1587302 0.1587302 0.1587302 0.0000000 0.1587302 0.1587302 0.1587302
+[8] 0.0000000       NaN
+
+##com.oracle.truffle.r.test.library.stats.TestDistributions.testDensityFunctions#Output.MayIgnoreWarningContext#
+#dunif(c(-3, 2, 3.3, -Inf, -0.42e-30, 0, 0.42e-30, Inf, NaN), -3, 3.3, log=T)
+[1] -1.84055 -1.84055 -1.84055     -Inf -1.84055 -1.84055 -1.84055     -Inf
+[9]      NaN
+
+##com.oracle.truffle.r.test.library.stats.TestDistributions.testDistributionFunctions#Output.MayIgnoreWarningContext#
+#pbeta(0, -1,  0.5)
+[1] NaN
+Warning message:
+In pbeta(0, -1, 0.5) : NaNs produced
+
+##com.oracle.truffle.r.test.library.stats.TestDistributions.testDistributionFunctions#Output.MayIgnoreWarningContext#
+#pbeta(0, -4,  15,  0)
+[1] 0
+
+##com.oracle.truffle.r.test.library.stats.TestDistributions.testDistributionFunctions#Output.MayIgnoreWarningContext#
+#pbeta(0, -Inf,  0.5)
+[1] NaN
+Warning message:
+In pbeta(0, -Inf, 0.5) : NaNs produced
+
+##com.oracle.truffle.r.test.library.stats.TestDistributions.testDistributionFunctions#Output.MayIgnoreWarningContext#
+#pbeta(0, -Inf,  15,  0)
+[1] 0
+
+##com.oracle.truffle.r.test.library.stats.TestDistributions.testDistributionFunctions#Output.MayIgnoreWarningContext#
+#pbeta(0, 0,  0.5)
+[1] 0
+
+##com.oracle.truffle.r.test.library.stats.TestDistributions.testDistributionFunctions#Output.MayIgnoreWarningContext#
+#pbeta(0, 0,  15,  0)
+[1] 0
+
+##com.oracle.truffle.r.test.library.stats.TestDistributions.testDistributionFunctions#Output.MayIgnoreWarningContext#
+#pbeta(0, 0.5, -1)
+[1] NaN
+Warning message:
+In pbeta(0, 0.5, -1) : NaNs produced
+
+##com.oracle.truffle.r.test.library.stats.TestDistributions.testDistributionFunctions#Output.MayIgnoreWarningContext#
+#pbeta(0, 0.5, -Inf)
+[1] NaN
+Warning message:
+In pbeta(0, 0.5, -Inf) : NaNs produced
+
+##com.oracle.truffle.r.test.library.stats.TestDistributions.testDistributionFunctions#Output.MayIgnoreWarningContext#
+#pbeta(0, 0.5, 0)
+[1] 0
+
+##com.oracle.truffle.r.test.library.stats.TestDistributions.testDistributionFunctions#Output.MayIgnoreWarningContext#
+#pbeta(0, 0.5, Inf)
+[1] 0
+
+##com.oracle.truffle.r.test.library.stats.TestDistributions.testDistributionFunctions#Output.MayIgnoreWarningContext#
+#pbeta(0, 0.5, NaN)
+[1] NaN
+
+##com.oracle.truffle.r.test.library.stats.TestDistributions.testDistributionFunctions#Output.MayIgnoreWarningContext#
+#pbeta(0, 10,  15, -4)
+[1] 0
+
+##com.oracle.truffle.r.test.library.stats.TestDistributions.testDistributionFunctions#Output.MayIgnoreWarningContext#
+#pbeta(0, 10,  15, -Inf)
+[1] 0
+
+##com.oracle.truffle.r.test.library.stats.TestDistributions.testDistributionFunctions#Output.MayIgnoreWarningContext#
+#pbeta(0, 10,  15, 0)
+[1] 0
+
+##com.oracle.truffle.r.test.library.stats.TestDistributions.testDistributionFunctions#Output.MayIgnoreWarningContext#
+#pbeta(0, 10,  15, Inf)
+[1] 0
+
+##com.oracle.truffle.r.test.library.stats.TestDistributions.testDistributionFunctions#Output.MayIgnoreWarningContext#
+#pbeta(0, 10,  15, NaN)
+[1] NaN
+
+##com.oracle.truffle.r.test.library.stats.TestDistributions.testDistributionFunctions#Output.MayIgnoreWarningContext#
+#pbeta(0, 10, -4,  0)
+[1] 0
+
+##com.oracle.truffle.r.test.library.stats.TestDistributions.testDistributionFunctions#Output.MayIgnoreWarningContext#
+#pbeta(0, 10, -Inf,  0)
+[1] 0
+
+##com.oracle.truffle.r.test.library.stats.TestDistributions.testDistributionFunctions#Output.MayIgnoreWarningContext#
+#pbeta(0, 10, 0,  0)
+[1] 0
+
+##com.oracle.truffle.r.test.library.stats.TestDistributions.testDistributionFunctions#Output.MayIgnoreWarningContext#
+#pbeta(0, 10, Inf,  0)
+[1] 0
+
+##com.oracle.truffle.r.test.library.stats.TestDistributions.testDistributionFunctions#Output.MayIgnoreWarningContext#
+#pbeta(0, 10, NaN,  0)
+[1] NaN
+
+##com.oracle.truffle.r.test.library.stats.TestDistributions.testDistributionFunctions#Output.MayIgnoreWarningContext#
+#pbeta(0, Inf,  0.5)
+[1] 0
+
+##com.oracle.truffle.r.test.library.stats.TestDistributions.testDistributionFunctions#Output.MayIgnoreWarningContext#
+#pbeta(0, Inf,  15,  0)
+[1] 0
+
+##com.oracle.truffle.r.test.library.stats.TestDistributions.testDistributionFunctions#Output.MayIgnoreWarningContext#
+#pbeta(0, NaN,  0.5)
+[1] NaN
+
+##com.oracle.truffle.r.test.library.stats.TestDistributions.testDistributionFunctions#Output.MayIgnoreWarningContext#
+#pbeta(0, NaN,  15,  0)
+[1] NaN
+
+##com.oracle.truffle.r.test.library.stats.TestDistributions.testDistributionFunctions#Output.MayIgnoreWarningContext#
+#pbeta(c(-Inf, -0.42e-30, 0, 0.42e-30, Inf, NaN), 0.5, 0.5, lower.tail=F, log.p=F)
+[1]   1   1   1   1   0 NaN
+
+##com.oracle.truffle.r.test.library.stats.TestDistributions.testDistributionFunctions#Output.MayIgnoreWarningContext#
+#pbeta(c(-Inf, -0.42e-30, 0, 0.42e-30, Inf, NaN), 0.5, 0.5, lower.tail=F, log.p=T)
+[1]  0.000000e+00  0.000000e+00  0.000000e+00 -4.125768e-16          -Inf
+[6]           NaN
+
+##com.oracle.truffle.r.test.library.stats.TestDistributions.testDistributionFunctions#Output.MayIgnoreWarningContext#
+#pbeta(c(-Inf, -0.42e-30, 0, 0.42e-30, Inf, NaN), 0.5, 0.5, lower.tail=T, log.p=F)
+[1] 0.000000e+00 0.000000e+00 0.000000e+00 4.125768e-16 1.000000e+00
+[6]          NaN
+
+##com.oracle.truffle.r.test.library.stats.TestDistributions.testDistributionFunctions#Output.MayIgnoreWarningContext#
+#pbeta(c(-Inf, -0.42e-30, 0, 0.42e-30, Inf, NaN), 0.5, 0.5, lower.tail=T, log.p=T)
+[1]      -Inf      -Inf      -Inf -35.42411   0.00000       NaN
+
+##com.oracle.truffle.r.test.library.stats.TestDistributions.testDistributionFunctions#Output.MayIgnoreWarningContext#
+#pbeta(c(0.2, -Inf, -0.42e-30, 0, 0.42e-30, Inf, NaN), 0.1, 3, lower.tail=F, log.p=F)
+[1] 0.05058572 1.00000000 1.00000000 1.00000000 0.99894097 0.00000000        NaN
+
+##com.oracle.truffle.r.test.library.stats.TestDistributions.testDistributionFunctions#Output.MayIgnoreWarningContext#
+#pbeta(c(0.2, -Inf, -0.42e-30, 0, 0.42e-30, Inf, NaN), 0.1, 3, lower.tail=F, log.p=T)
+[1] -2.984085987  0.000000000  0.000000000  0.000000000 -0.001059588
+[6]         -Inf          NaN
+
+##com.oracle.truffle.r.test.library.stats.TestDistributions.testDistributionFunctions#Output.MayIgnoreWarningContext#
+#pbeta(c(0.2, -Inf, -0.42e-30, 0, 0.42e-30, Inf, NaN), 0.1, 3, lower.tail=T, log.p=F)
+[1] 0.949414282 0.000000000 0.000000000 0.000000000 0.001059027 1.000000000
+[7]         NaN
+
+##com.oracle.truffle.r.test.library.stats.TestDistributions.testDistributionFunctions#Output.MayIgnoreWarningContext#
+#pbeta(c(0.2, -Inf, -0.42e-30, 0, 0.42e-30, Inf, NaN), 0.1, 3, lower.tail=T, log.p=T)
+[1] -0.05191003        -Inf        -Inf        -Inf -6.85040499  0.00000000
+[7]         NaN
+
+##com.oracle.truffle.r.test.library.stats.TestDistributions.testDistributionFunctions#Output.MayIgnoreWarningContext#
+#pbeta(c(0.4, -Inf, -0.42e-30, 0, 0.42e-30, Inf, NaN), 0, 0, lower.tail=F, log.p=F)
+[1] 0.5 1.0 1.0 1.0 0.5 0.0 NaN
+
+##com.oracle.truffle.r.test.library.stats.TestDistributions.testDistributionFunctions#Output.MayIgnoreWarningContext#
+#pbeta(c(0.4, -Inf, -0.42e-30, 0, 0.42e-30, Inf, NaN), 0, 0, lower.tail=F, log.p=T)
+[1] -0.6931472  0.0000000  0.0000000  0.0000000 -0.6931472       -Inf        NaN
+
+##com.oracle.truffle.r.test.library.stats.TestDistributions.testDistributionFunctions#Output.MayIgnoreWarningContext#
+#pbeta(c(0.4, -Inf, -0.42e-30, 0, 0.42e-30, Inf, NaN), 0, 0, lower.tail=T, log.p=F)
+[1] 0.5 0.0 0.0 0.0 0.5 1.0 NaN
+
+##com.oracle.truffle.r.test.library.stats.TestDistributions.testDistributionFunctions#Output.MayIgnoreWarningContext#
+#pbeta(c(0.4, -Inf, -0.42e-30, 0, 0.42e-30, Inf, NaN), 0, 0, lower.tail=T, log.p=T)
+[1] -0.6931472       -Inf       -Inf       -Inf -0.6931472  0.0000000        NaN
+
+##com.oracle.truffle.r.test.library.stats.TestDistributions.testDistributionFunctions#Output.MayIgnoreWarningContext#
+#pbeta(c(0.5, -Inf, -0.42e-30, 0, 0.42e-30, Inf, NaN), 0, Inf, lower.tail=F, log.p=F)
+[1]   0   1   1   1   0   0 NaN
+
+##com.oracle.truffle.r.test.library.stats.TestDistributions.testDistributionFunctions#Output.MayIgnoreWarningContext#
+#pbeta(c(0.5, -Inf, -0.42e-30, 0, 0.42e-30, Inf, NaN), 0, Inf, lower.tail=F, log.p=T)
+[1] -Inf    0    0    0 -Inf -Inf  NaN
+
+##com.oracle.truffle.r.test.library.stats.TestDistributions.testDistributionFunctions#Output.MayIgnoreWarningContext#
+#pbeta(c(0.5, -Inf, -0.42e-30, 0, 0.42e-30, Inf, NaN), 0, Inf, lower.tail=T, log.p=F)
+[1]   1   0   0   0   1   1 NaN
+
+##com.oracle.truffle.r.test.library.stats.TestDistributions.testDistributionFunctions#Output.MayIgnoreWarningContext#
+#pbeta(c(0.5, -Inf, -0.42e-30, 0, 0.42e-30, Inf, NaN), 0, Inf, lower.tail=T, log.p=T)
+[1]    0 -Inf -Inf -Inf    0    0  NaN
+
+##com.oracle.truffle.r.test.library.stats.TestDistributions.testDistributionFunctions#Output.MayIgnoreWarningContext#
+#pbeta(c(0.5, -Inf, -0.42e-30, 0, 0.42e-30, Inf, NaN), 2, 5, lower.tail=F, log.p=F)
+[1] 0.109375 1.000000 1.000000 1.000000 1.000000 0.000000      NaN
+
+##com.oracle.truffle.r.test.library.stats.TestDistributions.testDistributionFunctions#Output.MayIgnoreWarningContext#
+#pbeta(c(0.5, -Inf, -0.42e-30, 0, 0.42e-30, Inf, NaN), 2, 5, lower.tail=F, log.p=T)
+[1] -2.212973e+00  0.000000e+00  0.000000e+00  0.000000e+00 -2.646000e-60
+[6]          -Inf           NaN
+
+##com.oracle.truffle.r.test.library.stats.TestDistributions.testDistributionFunctions#Output.MayIgnoreWarningContext#
+#pbeta(c(0.5, -Inf, -0.42e-30, 0, 0.42e-30, Inf, NaN), 2, 5, lower.tail=T, log.p=F)
+[1] 8.90625e-01 0.00000e+00 0.00000e+00 0.00000e+00 2.64600e-60 1.00000e+00
+[7]         NaN
+
+##com.oracle.truffle.r.test.library.stats.TestDistributions.testDistributionFunctions#Output.MayIgnoreWarningContext#
+#pbeta(c(0.5, -Inf, -0.42e-30, 0, 0.42e-30, Inf, NaN), 2, 5, lower.tail=T, log.p=T)
+[1]   -0.1158318         -Inf         -Inf         -Inf -137.1820565
+[6]    0.0000000          NaN
+
+##com.oracle.truffle.r.test.library.stats.TestDistributions.testDistributionFunctions#Output.MayIgnoreWarningContext#
+#pbeta(c(0.6, -Inf, -0.42e-30, 0, 0.42e-30, Inf, NaN), Inf, 0, lower.tail=F, log.p=F)
+[1]   1   1   1   1   1   0 NaN
+
+##com.oracle.truffle.r.test.library.stats.TestDistributions.testDistributionFunctions#Output.MayIgnoreWarningContext#
+#pbeta(c(0.6, -Inf, -0.42e-30, 0, 0.42e-30, Inf, NaN), Inf, 0, lower.tail=F, log.p=T)
+[1]    0    0    0    0    0 -Inf  NaN
+
+##com.oracle.truffle.r.test.library.stats.TestDistributions.testDistributionFunctions#Output.MayIgnoreWarningContext#
+#pbeta(c(0.6, -Inf, -0.42e-30, 0, 0.42e-30, Inf, NaN), Inf, 0, lower.tail=T, log.p=F)
+[1]   0   0   0   0   0   1 NaN
+
+##com.oracle.truffle.r.test.library.stats.TestDistributions.testDistributionFunctions#Output.MayIgnoreWarningContext#
+#pbeta(c(0.6, -Inf, -0.42e-30, 0, 0.42e-30, Inf, NaN), Inf, 0, lower.tail=T, log.p=T)
+[1] -Inf -Inf -Inf -Inf -Inf    0  NaN
+
+##com.oracle.truffle.r.test.library.stats.TestDistributions.testDistributionFunctions#Output.MayIgnoreWarningContext#
+#pbeta(c(0.6, 0.1, 42e-33), 6, 3, lower.tail=F, log.p=F)
+[1] 0.6846054 0.9999766 1.0000000
+
+##com.oracle.truffle.r.test.library.stats.TestDistributions.testDistributionFunctions#Output.MayIgnoreWarningContext#
+#pbeta(c(0.6, 0.1, 42e-33), 6, 3, lower.tail=F, log.p=T)
+[1]  -3.789126e-01  -2.341027e-05 -1.536929e-187
+
+##com.oracle.truffle.r.test.library.stats.TestDistributions.testDistributionFunctions#Output.MayIgnoreWarningContext#
+#pbeta(c(0.6, 0.1, 42e-33), 6, 3, lower.tail=T, log.p=F)
+[1]  3.153946e-01  2.341000e-05 1.536929e-187
+
+##com.oracle.truffle.r.test.library.stats.TestDistributions.testDistributionFunctions#Output.MayIgnoreWarningContext#
+#pbeta(c(0.6, 0.1, 42e-33), 6, 3, lower.tail=T, log.p=T)
+[1]   -1.153931  -10.662347 -430.153626
+
+##com.oracle.truffle.r.test.library.stats.TestDistributions.testDistributionFunctions#Output.MayIgnoreWarningContext#
+#pbeta(c(10, 15, 100), 7, 11, 0.37e-10, lower.tail=F, log.p=F)
+[1] 0 0 0
+
+##com.oracle.truffle.r.test.library.stats.TestDistributions.testDistributionFunctions#Output.MayIgnoreWarningContext#
+#pbeta(c(10, 15, 100), 7, 11, 0.37e-10, lower.tail=F, log.p=T)
+[1] -Inf -Inf -Inf
+
+##com.oracle.truffle.r.test.library.stats.TestDistributions.testDistributionFunctions#Output.MayIgnoreWarningContext#
+#pbeta(c(10, 15, 100), 7, 11, 0.37e-10, lower.tail=T, log.p=F)
+[1] 1 1 1
+
+##com.oracle.truffle.r.test.library.stats.TestDistributions.testDistributionFunctions#Output.MayIgnoreWarningContext#
+#pbeta(c(10, 15, 100), 7, 11, 0.37e-10, lower.tail=T, log.p=T)
+[1] 0 0 0
+
+##com.oracle.truffle.r.test.library.stats.TestDistributions.testDistributionFunctions#Output.MayIgnoreWarningContext#
+#pbeta(c(10, 15, 100), 7, 113e11, 1, lower.tail=F, log.p=F)
+[1] 0 0 0
+
+##com.oracle.truffle.r.test.library.stats.TestDistributions.testDistributionFunctions#Output.MayIgnoreWarningContext#
+#pbeta(c(10, 15, 100), 7, 113e11, 1, lower.tail=F, log.p=T)
+[1] -Inf -Inf -Inf
+
+##com.oracle.truffle.r.test.library.stats.TestDistributions.testDistributionFunctions#Output.MayIgnoreWarningContext#
+#pbeta(c(10, 15, 100), 7, 113e11, 1, lower.tail=T, log.p=F)
+[1] 1 1 1
+
+##com.oracle.truffle.r.test.library.stats.TestDistributions.testDistributionFunctions#Output.MayIgnoreWarningContext#
+#pbeta(c(10, 15, 100), 7, 113e11, 1, lower.tail=T, log.p=T)
+[1] 0 0 0
+
+##com.oracle.truffle.r.test.library.stats.TestDistributions.testDistributionFunctions#Output.MayIgnoreWarningContext#
+#pbeta(c(10, 15, 100, -Inf, -0.42e-30, 0, 0.42e-30, Inf, NaN), 10, 15, 0, lower.tail=F, log.p=F)
+[1]   0   0   0   1   1   1   1   0 NaN
+
+##com.oracle.truffle.r.test.library.stats.TestDistributions.testDistributionFunctions#Output.MayIgnoreWarningContext#
+#pbeta(c(10, 15, 100, -Inf, -0.42e-30, 0, 0.42e-30, Inf, NaN), 10, 15, 0, lower.tail=F, log.p=T)
+[1]           -Inf           -Inf           -Inf   0.000000e+00   0.000000e+00
+[6]   0.000000e+00 -3.349864e-298           -Inf            NaN
+
+##com.oracle.truffle.r.test.library.stats.TestDistributions.testDistributionFunctions#Output.MayIgnoreWarningContext#
+#pbeta(c(10, 15, 100, -Inf, -0.42e-30, 0, 0.42e-30, Inf, NaN), 10, 15, 0, lower.tail=T, log.p=F)
+[1]  1.000000e+00  1.000000e+00  1.000000e+00  0.000000e+00  0.000000e+00
+[6]  0.000000e+00 3.349864e-298  1.000000e+00           NaN
+
+##com.oracle.truffle.r.test.library.stats.TestDistributions.testDistributionFunctions#Output.MayIgnoreWarningContext#
+#pbeta(c(10, 15, 100, -Inf, -0.42e-30, 0, 0.42e-30, Inf, NaN), 10, 15, 0, lower.tail=T, log.p=T)
+[1]    0.0000    0.0000    0.0000      -Inf      -Inf      -Inf -684.9614
+[8]    0.0000       NaN
+
+##com.oracle.truffle.r.test.library.stats.TestDistributions.testDistributionFunctions#Output.MayIgnoreWarningContext#
+#pbeta(c(10, 15, 100, -Inf, -0.42e-30, 0, 0.42e-30, Inf, NaN), 7, 13, 3, lower.tail=F, log.p=F)
+[1]   0   0   0   1   1   1   1   0 NaN
+
+##com.oracle.truffle.r.test.library.stats.TestDistributions.testDistributionFunctions#Output.MayIgnoreWarningContext#
+#pbeta(c(10, 15, 100, -Inf, -0.42e-30, 0, 0.42e-30, Inf, NaN), 7, 13, 3, lower.tail=F, log.p=T)
+[1]           -Inf           -Inf           -Inf   0.000000e+00   0.000000e+00
+[6]   0.000000e+00 -2.591973e-209           -Inf            NaN
+
+##com.oracle.truffle.r.test.library.stats.TestDistributions.testDistributionFunctions#Output.MayIgnoreWarningContext#
+#pbeta(c(10, 15, 100, -Inf, -0.42e-30, 0, 0.42e-30, Inf, NaN), 7, 13, 3, lower.tail=T, log.p=F)
+[1]  1.000000e+00  1.000000e+00  1.000000e+00  0.000000e+00  0.000000e+00
+[6]  0.000000e+00 2.591973e-209  1.000000e+00           NaN
+
+##com.oracle.truffle.r.test.library.stats.TestDistributions.testDistributionFunctions#Output.MayIgnoreWarningContext#
+#pbeta(c(10, 15, 100, -Inf, -0.42e-30, 0, 0.42e-30, Inf, NaN), 7, 13, 3, lower.tail=T, log.p=T)
+[1]    0.0000    0.0000    0.0000      -Inf      -Inf      -Inf -480.2879
+[8]    0.0000       NaN
+
+##com.oracle.truffle.r.test.library.stats.TestDistributions.testDistributionFunctions#Output.MayIgnoreWarningContext#
+#pcauchy(0, -Inf,  -1)
+[1] NaN
+Warning message:
+In pcauchy(0, -Inf, -1) : NaNs produced
+
+##com.oracle.truffle.r.test.library.stats.TestDistributions.testDistributionFunctions#Output.MayIgnoreWarningContext#
+#pcauchy(0, 0, -Inf)
+[1] NaN
+Warning message:
+In pcauchy(0, 0, -Inf) : NaNs produced
+
+##com.oracle.truffle.r.test.library.stats.TestDistributions.testDistributionFunctions#Output.MayIgnoreWarningContext#
+#pcauchy(0, 0, Inf)
+[1] 0.5
+
+##com.oracle.truffle.r.test.library.stats.TestDistributions.testDistributionFunctions#Output.MayIgnoreWarningContext#
+#pcauchy(0, 0, NaN)
+[1] NaN
+
+##com.oracle.truffle.r.test.library.stats.TestDistributions.testDistributionFunctions#Output.MayIgnoreWarningContext#
+#pcauchy(0, Inf,  -1)
+[1] NaN
+Warning message:
+In pcauchy(0, Inf, -1) : NaNs produced
+
+##com.oracle.truffle.r.test.library.stats.TestDistributions.testDistributionFunctions#Output.MayIgnoreWarningContext#
+#pcauchy(0, NaN,  -1)
+[1] NaN
+
+##com.oracle.truffle.r.test.library.stats.TestDistributions.testDistributionFunctions#Output.MayIgnoreWarningContext#
+#pcauchy(c(-5, 42, -Inf, -0.42e-30, 0, 0.42e-30, Inf, NaN), -5, 5, lower.tail=F, log.p=F)
+[1] 0.50000000 0.03373587 1.00000000 0.25000000 0.25000000 0.25000000 0.00000000
+[8]        NaN
+
+##com.oracle.truffle.r.test.library.stats.TestDistributions.testDistributionFunctions#Output.MayIgnoreWarningContext#
+#pcauchy(c(-5, 42, -Inf, -0.42e-30, 0, 0.42e-30, Inf, NaN), -5, 5, lower.tail=F, log.p=T)
+[1] -0.6931472 -3.3891936  0.0000000 -1.3862944 -1.3862944 -1.3862944       -Inf
+[8]        NaN
+
+##com.oracle.truffle.r.test.library.stats.TestDistributions.testDistributionFunctions#Output.MayIgnoreWarningContext#
+#pcauchy(c(-5, 42, -Inf, -0.42e-30, 0, 0.42e-30, Inf, NaN), -5, 5, lower.tail=T, log.p=F)
+[1] 0.5000000 0.9662641 0.0000000 0.7500000 0.7500000 0.7500000 1.0000000
+[8]       NaN
+
+##com.oracle.truffle.r.test.library.stats.TestDistributions.testDistributionFunctions#Output.MayIgnoreWarningContext#
+#pcauchy(c(-5, 42, -Inf, -0.42e-30, 0, 0.42e-30, Inf, NaN), -5, 5, lower.tail=T, log.p=T)
+[1] -0.69314718 -0.03431805        -Inf -0.28768207 -0.28768207 -0.28768207
+[7]  0.00000000         NaN
+
+##com.oracle.truffle.r.test.library.stats.TestDistributions.testDistributionFunctions#Output.MayIgnoreWarningContext#
+#pcauchy(c(0, -1, 1, 0.42e-30), -0.01, 0.03, lower.tail=F, log.p=F)
+[1] 0.39758362 0.99035720 0.00945197 0.39758362
+
+##com.oracle.truffle.r.test.library.stats.TestDistributions.testDistributionFunctions#Output.MayIgnoreWarningContext#
+#pcauchy(c(0, -1, 1, 0.42e-30), -0.01, 0.03, lower.tail=F, log.p=T)
+[1] -0.922350008 -0.009689596 -4.661532090 -0.922350008
+
+##com.oracle.truffle.r.test.library.stats.TestDistributions.testDistributionFunctions#Output.MayIgnoreWarningContext#
+#pcauchy(c(0, -1, 1, 0.42e-30), -0.01, 0.03, lower.tail=T, log.p=F)
+[1] 0.602416382 0.009642803 0.990548030 0.602416382
+
+##com.oracle.truffle.r.test.library.stats.TestDistributions.testDistributionFunctions#Output.MayIgnoreWarningContext#
+#pcauchy(c(0, -1, 1, 0.42e-30), -0.01, 0.03, lower.tail=T, log.p=T)
+[1] -0.506806408 -4.641543417 -0.009496923 -0.506806408
+
+##com.oracle.truffle.r.test.library.stats.TestDistributions.testDistributionFunctions#Output.MayIgnoreWarningContext#
+#pcauchy(c(0, -1, 42), 0, -1, lower.tail=F, log.p=F)
+[1] NaN NaN NaN
+Warning message:
+In pcauchy(c(0, -1, 42), 0, -1, lower.tail = F, log.p = F) : NaNs produced
+
+##com.oracle.truffle.r.test.library.stats.TestDistributions.testDistributionFunctions#Output.MayIgnoreWarningContext#
+#pcauchy(c(0, -1, 42), 0, -1, lower.tail=F, log.p=T)
+[1] NaN NaN NaN
+Warning message:
+In pcauchy(c(0, -1, 42), 0, -1, lower.tail = F, log.p = T) : NaNs produced
+
+##com.oracle.truffle.r.test.library.stats.TestDistributions.testDistributionFunctions#Output.MayIgnoreWarningContext#
+#pcauchy(c(0, -1, 42), 0, -1, lower.tail=T, log.p=F)
+[1] NaN NaN NaN
+Warning message:
+In pcauchy(c(0, -1, 42), 0, -1, lower.tail = T, log.p = F) : NaNs produced
+
+##com.oracle.truffle.r.test.library.stats.TestDistributions.testDistributionFunctions#Output.MayIgnoreWarningContext#
+#pcauchy(c(0, -1, 42), 0, -1, lower.tail=T, log.p=T)
+[1] NaN NaN NaN
+Warning message:
+In pcauchy(c(0, -1, 42), 0, -1, lower.tail = T, log.p = T) : NaNs produced
+
+##com.oracle.truffle.r.test.library.stats.TestDistributions.testDistributionFunctions#Output.MayIgnoreWarningContext#
+#pchisq(0, -3,  1)
+[1] NaN
+Warning message:
+In pchisq(0, -3, 1) : NaNs produced
+
+##com.oracle.truffle.r.test.library.stats.TestDistributions.testDistributionFunctions#Output.MayIgnoreWarningContext#
+#pchisq(0, -Inf,  1)
+[1] NaN
+Warning message:
+In pchisq(0, -Inf, 1) : NaNs produced
+
+##com.oracle.truffle.r.test.library.stats.TestDistributions.testDistributionFunctions#Output.MayIgnoreWarningContext#
+#pchisq(0, 0,  1)
+[1] 0.6065307
+
+##com.oracle.truffle.r.test.library.stats.TestDistributions.testDistributionFunctions#Output.MayIgnoreWarningContext#
+#pchisq(0, 1, -3)
+[1] NaN
+Warning message:
+In pchisq(0, 1, -3) : NaNs produced
+
+##com.oracle.truffle.r.test.library.stats.TestDistributions.testDistributionFunctions#Output.MayIgnoreWarningContext#
+#pchisq(0, 1, -Inf)
+[1] NaN
+Warning message:
+In pchisq(0, 1, -Inf) : NaNs produced
+
+##com.oracle.truffle.r.test.library.stats.TestDistributions.testDistributionFunctions#Output.MayIgnoreWarningContext#
+#pchisq(0, 1, 0)
+[1] 0
+
+##com.oracle.truffle.r.test.library.stats.TestDistributions.testDistributionFunctions#Output.MayIgnoreWarningContext#
+#pchisq(0, 1, Inf)
+[1] NaN
+Warning message:
+In pchisq(0, 1, Inf) : NaNs produced
+
+##com.oracle.truffle.r.test.library.stats.TestDistributions.testDistributionFunctions#Output.MayIgnoreWarningContext#
+#pchisq(0, 1, NaN)
+[1] NaN
+
+##com.oracle.truffle.r.test.library.stats.TestDistributions.testDistributionFunctions#Output.MayIgnoreWarningContext#
+#pchisq(0, Inf,  1)
+[1] NaN
+Warning message:
+In pchisq(0, Inf, 1) : NaNs produced
+
+##com.oracle.truffle.r.test.library.stats.TestDistributions.testDistributionFunctions#Output.MayIgnoreWarningContext#
+#pchisq(0, NaN,  1)
+[1] NaN
+
+##com.oracle.truffle.r.test.library.stats.TestDistributions.testDistributionFunctions#Output.MayIgnoreWarningContext#
+#pchisq(c(0.42e-10, 100, 13e10, 11e111), 0.13e-8, 1, lower.tail=F, log.p=F)
+[1] 3.934693e-01 3.413625e-20 0.000000e+00 0.000000e+00
+
+##com.oracle.truffle.r.test.library.stats.TestDistributions.testDistributionFunctions#Output.MayIgnoreWarningContext#
+#pchisq(c(0.42e-10, 100, 13e10, 11e111), 0.13e-8, 1, lower.tail=F, log.p=T)
+[1]  -0.9327521 -44.8239272        -Inf        -Inf
+
+##com.oracle.truffle.r.test.library.stats.TestDistributions.testDistributionFunctions#Output.MayIgnoreWarningContext#
+#pchisq(c(0.42e-10, 100, 13e10, 11e111), 0.13e-8, 1, lower.tail=T, log.p=F)
+[1] 0.6065307 1.0000000 1.0000000 1.0000000
+
+##com.oracle.truffle.r.test.library.stats.TestDistributions.testDistributionFunctions#Output.MayIgnoreWarningContext#
+#pchisq(c(0.42e-10, 100, 13e10, 11e111), 0.13e-8, 1, lower.tail=T, log.p=T)
+[1] -5.000000e-01 -3.413625e-20  0.000000e+00  0.000000e+00
+
+##com.oracle.truffle.r.test.library.stats.TestDistributions.testDistributionFunctions#Output.MayIgnoreWarningContext#
+#pchisq(c(0.42e-10, 100, 13e10, 11e111), 1, 0.13e-8, lower.tail=F, log.p=F)
+[1] 9.999948e-01 1.523971e-23 0.000000e+00 0.000000e+00
+
+##com.oracle.truffle.r.test.library.stats.TestDistributions.testDistributionFunctions#Output.MayIgnoreWarningContext#
+#pchisq(c(0.42e-10, 100, 13e10, 11e111), 1, 0.13e-8, lower.tail=F, log.p=T)
+[1] -5.170896e-06 -5.253814e+01          -Inf          -Inf
+
+##com.oracle.truffle.r.test.library.stats.TestDistributions.testDistributionFunctions#Output.MayIgnoreWarningContext#
+#pchisq(c(0.42e-10, 100, 13e10, 11e111), 1, 0.13e-8, lower.tail=T, log.p=F)
+[1] 5.170883e-06 1.000000e+00 1.000000e+00 1.000000e+00
+
+##com.oracle.truffle.r.test.library.stats.TestDistributions.testDistributionFunctions#Output.MayIgnoreWarningContext#
+#pchisq(c(0.42e-10, 100, 13e10, 11e111), 1, 0.13e-8, lower.tail=T, log.p=T)
+[1] -1.217247e+01 -1.523971e-23  0.000000e+00  0.000000e+00
+
+##com.oracle.truffle.r.test.library.stats.TestDistributions.testDistributionFunctions#Output.MayIgnoreWarningContext#
+#pchisq(c(0.42e-10, 100, 13e10, 11e111), 420, 4, lower.tail=F, log.p=F)
+[1] 1 1 0 0
+
+##com.oracle.truffle.r.test.library.stats.TestDistributions.testDistributionFunctions#Output.MayIgnoreWarningContext#
+#pchisq(c(0.42e-10, 100, 13e10, 11e111), 420, 4, lower.tail=F, log.p=T)
+[1]  0.000000e+00 -3.150394e-64          -Inf          -Inf
+
+##com.oracle.truffle.r.test.library.stats.TestDistributions.testDistributionFunctions#Output.MayIgnoreWarningContext#
+#pchisq(c(0.42e-10, 100, 13e10, 11e111), 420, 4, lower.tail=T, log.p=F)
+[1] 0.000000e+00 3.150394e-64 1.000000e+00 1.000000e+00
+
+##com.oracle.truffle.r.test.library.stats.TestDistributions.testDistributionFunctions#Output.MayIgnoreWarningContext#
+#pchisq(c(0.42e-10, 100, 13e10, 11e111), 420, 4, lower.tail=T, log.p=T)
+[1] -6081.6502  -146.2179     0.0000     0.0000
+
+##com.oracle.truffle.r.test.library.stats.TestDistributions.testDistributionFunctions#Output.MayIgnoreWarningContext#
+#pchisq(c(0.5, 2, -Inf, -0.42e-30, 0, 0.42e-30, Inf, NaN), 1, 1, lower.tail=F, log.p=F)
+[1] 0.6590992 0.3472435 1.0000000 1.0000000 1.0000000 1.0000000 0.0000000
+[8]       NaN
+
+##com.oracle.truffle.r.test.library.stats.TestDistributions.testDistributionFunctions#Output.MayIgnoreWarningContext#
+#pchisq(c(0.5, 2, -Inf, -0.42e-30, 0, 0.42e-30, Inf, NaN), 1, 1, lower.tail=F, log.p=T)
+[1] -4.168812e-01 -1.057729e+00  0.000000e+00  0.000000e+00  0.000000e+00
+[6] -3.136299e-16          -Inf           NaN
+
+##com.oracle.truffle.r.test.library.stats.TestDistributions.testDistributionFunctions#Output.MayIgnoreWarningContext#
+#pchisq(c(0.5, 2, -Inf, -0.42e-30, 0, 0.42e-30, Inf, NaN), 1, 1, lower.tail=T, log.p=F)
+[1] 3.409008e-01 6.527565e-01 0.000000e+00 0.000000e+00 0.000000e+00
+[6] 3.136299e-16 1.000000e+00          NaN
+
+##com.oracle.truffle.r.test.library.stats.TestDistributions.testDistributionFunctions#Output.MayIgnoreWarningContext#
+#pchisq(c(0.5, 2, -Inf, -0.42e-30, 0, 0.42e-30, Inf, NaN), 1, 1, lower.tail=T, log.p=T)
+[1]  -1.0761638  -0.4265511        -Inf        -Inf        -Inf -35.6983180
+[7]   0.0000000         NaN
+
+##com.oracle.truffle.r.test.library.stats.TestDistributions.testDistributionFunctions#Output.MayIgnoreWarningContext#
+#pexp(0, -1)
+[1] NaN
+Warning message:
+In pexp(0, -1) : NaNs produced
+
+##com.oracle.truffle.r.test.library.stats.TestDistributions.testDistributionFunctions#Output.MayIgnoreWarningContext#
+#pexp(0, -Inf)
+[1] 0
+
+##com.oracle.truffle.r.test.library.stats.TestDistributions.testDistributionFunctions#Output.MayIgnoreWarningContext#
+#pexp(0, 0)
+[1] 0
+
+##com.oracle.truffle.r.test.library.stats.TestDistributions.testDistributionFunctions#Output.MayIgnoreWarningContext#
+#pexp(0, Inf)
+[1] 0
+
+##com.oracle.truffle.r.test.library.stats.TestDistributions.testDistributionFunctions#Output.MayIgnoreWarningContext#
+#pexp(0, NaN)
+[1] NaN
+
+##com.oracle.truffle.r.test.library.stats.TestDistributions.testDistributionFunctions#Output.MayIgnoreWarningContext#
+#pexp(c(10, -10, -Inf, -0.42e-30, 0, 0.42e-30, Inf, NaN), 13e-20, lower.tail=F, log.p=F)
+[1]   1   1   1   1   1   1   0 NaN
+
+##com.oracle.truffle.r.test.library.stats.TestDistributions.testDistributionFunctions#Output.MayIgnoreWarningContext#
+#pexp(c(10, -10, -Inf, -0.42e-30, 0, 0.42e-30, Inf, NaN), 13e-20, lower.tail=F, log.p=T)
+[1] -1.30e-18  0.00e+00  0.00e+00  0.00e+00  0.00e+00 -5.46e-50      -Inf
+[8]       NaN
+
+##com.oracle.truffle.r.test.library.stats.TestDistributions.testDistributionFunctions#Output.MayIgnoreWarningContext#
+#pexp(c(10, -10, -Inf, -0.42e-30, 0, 0.42e-30, Inf, NaN), 13e-20, lower.tail=T, log.p=F)
+[1] 1.30e-18 0.00e+00 0.00e+00 0.00e+00 0.00e+00 5.46e-50 1.00e+00      NaN
+
+##com.oracle.truffle.r.test.library.stats.TestDistributions.testDistributionFunctions#Output.MayIgnoreWarningContext#
+#pexp(c(10, -10, -Inf, -0.42e-30, 0, 0.42e-30, Inf, NaN), 13e-20, lower.tail=T, log.p=T)
+[1]  -41.18417       -Inf       -Inf       -Inf       -Inf -113.43181    0.00000
+[8]        NaN
+
+##com.oracle.truffle.r.test.library.stats.TestDistributions.testDistributionFunctions#Output.MayIgnoreWarningContext#
+#pexp(c(33e123, -Inf, -0.42e-30, 0, 0.42e-30, Inf, NaN), 42e123, lower.tail=F, log.p=F)
+[1]   0   1   1   1   0   0 NaN
+
+##com.oracle.truffle.r.test.library.stats.TestDistributions.testDistributionFunctions#Output.MayIgnoreWarningContext#
+#pexp(c(33e123, -Inf, -0.42e-30, 0, 0.42e-30, Inf, NaN), 42e123, lower.tail=F, log.p=T)
+[1] -1.386e+249   0.000e+00   0.000e+00   0.000e+00  -1.764e+94        -Inf
+[7]         NaN
+
+##com.oracle.truffle.r.test.library.stats.TestDistributions.testDistributionFunctions#Output.MayIgnoreWarningContext#
+#pexp(c(33e123, -Inf, -0.42e-30, 0, 0.42e-30, Inf, NaN), 42e123, lower.tail=T, log.p=F)
+[1]   1   0   0   0   1   1 NaN
+
+##com.oracle.truffle.r.test.library.stats.TestDistributions.testDistributionFunctions#Output.MayIgnoreWarningContext#
+#pexp(c(33e123, -Inf, -0.42e-30, 0, 0.42e-30, Inf, NaN), 42e123, lower.tail=T, log.p=T)
+[1]    0 -Inf -Inf -Inf    0    0  NaN
+
+##com.oracle.truffle.r.test.library.stats.TestDistributions.testDistributionFunctions#Output.MayIgnoreWarningContext#
+#pexp(c(42, -Inf, -0.42e-30, 0, 0.42e-30, Inf, NaN), 42, lower.tail=F, log.p=F)
+[1]   0   1   1   1   1   0 NaN
+
+##com.oracle.truffle.r.test.library.stats.TestDistributions.testDistributionFunctions#Output.MayIgnoreWarningContext#
+#pexp(c(42, -Inf, -0.42e-30, 0, 0.42e-30, Inf, NaN), 42, lower.tail=F, log.p=T)
+[1] -1.764e+03  0.000e+00  0.000e+00  0.000e+00 -1.764e-29       -Inf        NaN
+
+##com.oracle.truffle.r.test.library.stats.TestDistributions.testDistributionFunctions#Output.MayIgnoreWarningContext#
+#pexp(c(42, -Inf, -0.42e-30, 0, 0.42e-30, Inf, NaN), 42, lower.tail=T, log.p=F)
+[1] 1.000e+00 0.000e+00 0.000e+00 0.000e+00 1.764e-29 1.000e+00       NaN
+
+##com.oracle.truffle.r.test.library.stats.TestDistributions.testDistributionFunctions#Output.MayIgnoreWarningContext#
+#pexp(c(42, -Inf, -0.42e-30, 0, 0.42e-30, Inf, NaN), 42, lower.tail=T, log.p=T)
+[1]   0.00000      -Inf      -Inf      -Inf -66.20738   0.00000       NaN
+
+##com.oracle.truffle.r.test.library.stats.TestDistributions.testDistributionFunctions#Output.MayIgnoreWarningContext#
+#pf(0, -1,  5,  5)
+[1] NaN
+Warning message:
+In pf(0, -1, 5, 5) : NaNs produced
+
+##com.oracle.truffle.r.test.library.stats.TestDistributions.testDistributionFunctions#Output.MayIgnoreWarningContext#
+#pf(0, -Inf,  5,  5)
+[1] NaN
+Warning message:
+In pf(0, -Inf, 5, 5) : NaNs produced
+
+##com.oracle.truffle.r.test.library.stats.TestDistributions.testDistributionFunctions#Output.MayIgnoreWarningContext#
+#pf(0, 0,  5,  5)
+[1] NaN
+Warning message:
+In pf(0, 0, 5, 5) : NaNs produced
+
+##com.oracle.truffle.r.test.library.stats.TestDistributions.testDistributionFunctions#Output.MayIgnoreWarningContext#
+#pf(0, 5,  5, -1)
+[1] NaN
+Warning message:
+In pf(0, 5, 5, -1) : NaNs produced
+
+##com.oracle.truffle.r.test.library.stats.TestDistributions.testDistributionFunctions#Output.MayIgnoreWarningContext#
+#pf(0, 5,  5, -Inf)
+[1] NaN
+Warning message:
+In pf(0, 5, 5, -Inf) : NaNs produced
+
+##com.oracle.truffle.r.test.library.stats.TestDistributions.testDistributionFunctions#Output.MayIgnoreWarningContext#
+#pf(0, 5,  5, 0)
+[1] 0
+
+##com.oracle.truffle.r.test.library.stats.TestDistributions.testDistributionFunctions#Output.MayIgnoreWarningContext#
+#pf(0, 5,  5, Inf)
+[1] NaN
+Warning message:
+In pf(0, 5, 5, Inf) : NaNs produced
+
+##com.oracle.truffle.r.test.library.stats.TestDistributions.testDistributionFunctions#Output.MayIgnoreWarningContext#
+#pf(0, 5,  5, NaN)
+[1] NaN
+
+##com.oracle.truffle.r.test.library.stats.TestDistributions.testDistributionFunctions#Output.MayIgnoreWarningContext#
+#pf(0, 5, -1,  5)
+[1] NaN
+Warning message:
+In pf(0, 5, -1, 5) : NaNs produced
+
+##com.oracle.truffle.r.test.library.stats.TestDistributions.testDistributionFunctions#Output.MayIgnoreWarningContext#
+#pf(0, 5, -Inf,  5)
+[1] NaN
+Warning message:
+In pf(0, 5, -Inf, 5) : NaNs produced
+
+##com.oracle.truffle.r.test.library.stats.TestDistributions.testDistributionFunctions#Output.MayIgnoreWarningContext#
+#pf(0, 5, 0,  5)
+[1] NaN
+Warning message:
+In pf(0, 5, 0, 5) : NaNs produced
+
+##com.oracle.truffle.r.test.library.stats.TestDistributions.testDistributionFunctions#Output.MayIgnoreWarningContext#
+#pf(0, 5, Inf,  5)
+[1] 0
+
+##com.oracle.truffle.r.test.library.stats.TestDistributions.testDistributionFunctions#Output.MayIgnoreWarningContext#
+#pf(0, 5, NaN,  5)
+[1] NaN
+
+##com.oracle.truffle.r.test.library.stats.TestDistributions.testDistributionFunctions#Output.MayIgnoreWarningContext#
+#pf(0, Inf,  5,  5)
+[1] 0
+
+##com.oracle.truffle.r.test.library.stats.TestDistributions.testDistributionFunctions#Output.MayIgnoreWarningContext#
+#pf(0, NaN,  5,  5)
+[1] NaN
+
+##com.oracle.truffle.r.test.library.stats.TestDistributions.testDistributionFunctions#Output.MayIgnoreWarningContext#
+#pf(c(1, 10, 44, 123, -Inf, -0.42e-30, 0, 0.42e-30, Inf, NaN), 0.12e-10, 6, 31e10, lower.tail=F, log.p=F)
+ [1]   1   1   1   1   1   1   1   1   0 NaN
+
+##com.oracle.truffle.r.test.library.stats.TestDistributions.testDistributionFunctions#Output.MayIgnoreWarningContext#
+#pf(c(1, 10, 44, 123, -Inf, -0.42e-30, 0, 0.42e-30, Inf, NaN), 0.12e-10, 6, 31e10, lower.tail=F, log.p=T)
+ [1]    0    0    0    0    0    0    0    0 -Inf  NaN
+
+##com.oracle.truffle.r.test.library.stats.TestDistributions.testDistributionFunctions#Output.MayIgnoreWarningContext#
+#pf(c(1, 10, 44, 123, -Inf, -0.42e-30, 0, 0.42e-30, Inf, NaN), 0.12e-10, 6, 31e10, lower.tail=T, log.p=F)
+ [1]   0   0   0   0   0   0   0   0   1 NaN
+
+##com.oracle.truffle.r.test.library.stats.TestDistributions.testDistributionFunctions#Output.MayIgnoreWarningContext#
+#pf(c(1, 10, 44, 123, -Inf, -0.42e-30, 0, 0.42e-30, Inf, NaN), 0.12e-10, 6, 31e10, lower.tail=T, log.p=T)
+ [1] -Inf -Inf -Inf -Inf -Inf -Inf -Inf -Inf    0  NaN
+
+##com.oracle.truffle.r.test.library.stats.TestDistributions.testDistributionFunctions#Output.MayIgnoreWarningContext#
+#pf(c(1, 10, 44, 123, -Inf, -0.42e-30, 0, 0.42e-30, Inf, NaN), 5, 0.12e-10, 5, lower.tail=F, log.p=F)
+ [1]   1   1   1   1   1   1   1   1   0 NaN
+
+##com.oracle.truffle.r.test.library.stats.TestDistributions.testDistributionFunctions#Output.MayIgnoreWarningContext#
+#pf(c(1, 10, 44, 123, -Inf, -0.42e-30, 0, 0.42e-30, Inf, NaN), 5, 0.12e-10, 5, lower.tail=F, log.p=T)
+ [1] -4.342122e-11 -4.739038e-11 -4.994435e-11 -5.171639e-11  0.000000e+00
+ [6]  0.000000e+00  0.000000e+00 -2.523888e-60          -Inf           NaN
+
+##com.oracle.truffle.r.test.library.stats.TestDistributions.testDistributionFunctions#Output.MayIgnoreWarningContext#
+#pf(c(1, 10, 44, 123, -Inf, -0.42e-30, 0, 0.42e-30, Inf, NaN), 5, 0.12e-10, 5, lower.tail=T, log.p=F)
+ [1] 4.342122e-11 4.739038e-11 4.994435e-11 5.171639e-11 0.000000e+00
+ [6] 0.000000e+00 0.000000e+00 2.523888e-60 1.000000e+00          NaN
+
+##com.oracle.truffle.r.test.library.stats.TestDistributions.testDistributionFunctions#Output.MayIgnoreWarningContext#
+#pf(c(1, 10, 44, 123, -Inf, -0.42e-30, 0, 0.42e-30, Inf, NaN), 5, 0.12e-10, 5, lower.tail=T, log.p=T)
+ [1]  -23.86007  -23.77260  -23.72011  -23.68525       -Inf       -Inf
+ [7]       -Inf -137.22930    0.00000        NaN
+
+##com.oracle.truffle.r.test.library.stats.TestDistributions.testDistributionFunctions#Output.MayIgnoreWarningContext#
+#pf(c(1, 10, 44, 123, -Inf, -0.42e-30, 0, 0.42e-30, Inf, NaN), 5, 5, 5, lower.tail=F, log.p=F)
+ [1] 0.7960368423 0.0481532307 0.0018278022 0.0001527094 1.0000000000
+ [6] 1.0000000000 1.0000000000 1.0000000000 0.0000000000          NaN
+
+##com.oracle.truffle.r.test.library.stats.TestDistributions.testDistributionFunctions#Output.MayIgnoreWarningContext#
+#pf(c(1, 10, 44, 123, -Inf, -0.42e-30, 0, 0.42e-30, Inf, NaN), 5, 5, 5, lower.tail=F, log.p=T)
+ [1] -2.281098e-01 -3.033367e+00 -6.304641e+00 -8.786974e+00  0.000000e+00
+ [6]  0.000000e+00  0.000000e+00 -5.097836e-77          -Inf           NaN
+
+##com.oracle.truffle.r.test.library.stats.TestDistributions.testDistributionFunctions#Output.MayIgnoreWarningContext#
+#pf(c(1, 10, 44, 123, -Inf, -0.42e-30, 0, 0.42e-30, Inf, NaN), 5, 5, 5, lower.tail=T, log.p=F)
+ [1] 2.039632e-01 9.518468e-01 9.981722e-01 9.998473e-01 0.000000e+00
+ [6] 0.000000e+00 0.000000e+00 5.097836e-77 1.000000e+00          NaN
+
+##com.oracle.truffle.r.test.library.stats.TestDistributions.testDistributionFunctions#Output.MayIgnoreWarningContext#
+#pf(c(1, 10, 44, 123, -Inf, -0.42e-30, 0, 0.42e-30, Inf, NaN), 5, 5, 5, lower.tail=T, log.p=T)
+ [1] -1.589816e+00 -4.935121e-02 -1.829475e-03 -1.527211e-04          -Inf
+ [6]          -Inf          -Inf -1.756702e+02  0.000000e+00           NaN
+
+##com.oracle.truffle.r.test.library.stats.TestDistributions.testDistributionFunctions#Output.MayIgnoreWarningContext#
+#pf(c(1, 10, 44, 123, -Inf, -0.42e-30, 0, 0.42e-30, Inf, NaN), 5, 6, 0.12e-10, lower.tail=F, log.p=F)
+ [1] 4.894344e-01 7.119843e-03 1.191517e-04 5.854787e-06 1.000000e+00
+ [6] 1.000000e+00 1.000000e+00 1.000000e+00 0.000000e+00          NaN
+
+##com.oracle.truffle.r.test.library.stats.TestDistributions.testDistributionFunctions#Output.MayIgnoreWarningContext#
+#pf(c(1, 10, 44, 123, -Inf, -0.42e-30, 0, 0.42e-30, Inf, NaN), 5, 6, 0.12e-10, lower.tail=F, log.p=T)
+ [1] -7.145048e-01 -4.944870e+00 -9.035113e+00 -1.204825e+01  0.000000e+00
+ [6]  0.000000e+00  0.000000e+00 -5.707168e-76          -Inf           NaN
+
+##com.oracle.truffle.r.test.library.stats.TestDistributions.testDistributionFunctions#Output.MayIgnoreWarningContext#
+#pf(c(1, 10, 44, 123, -Inf, -0.42e-30, 0, 0.42e-30, Inf, NaN), 5, 6, 0.12e-10, lower.tail=T, log.p=F)
+ [1] 5.105656e-01 9.928802e-01 9.998808e-01 9.999941e-01 0.000000e+00
+ [6] 0.000000e+00 0.000000e+00 5.707168e-76 1.000000e+00          NaN
+
+##com.oracle.truffle.r.test.library.stats.TestDistributions.testDistributionFunctions#Output.MayIgnoreWarningContext#
+#pf(c(1, 10, 44, 123, -Inf, -0.42e-30, 0, 0.42e-30, Inf, NaN), 5, 6, 0.12e-10, lower.tail=T, log.p=T)
+ [1] -6.722361e-01 -7.145310e-03 -1.191588e-04 -5.854804e-06          -Inf
+ [6]          -Inf          -Inf -1.732547e+02  0.000000e+00           NaN
+
+##com.oracle.truffle.r.test.library.stats.TestDistributions.testDistributionFunctions#Output.MayIgnoreWarningContext#
+#pgamma(0, -1,  scale=2)
+[1] NaN
+Warning message:
+In pgamma(0, -1, scale = 2) : NaNs produced
+
+##com.oracle.truffle.r.test.library.stats.TestDistributions.testDistributionFunctions#Output.MayIgnoreWarningContext#
+#pgamma(0, -Inf,  scale=2)
+[1] NaN
+Warning message:
+In pgamma(0, -Inf, scale = 2) : NaNs produced
+
+##com.oracle.truffle.r.test.library.stats.TestDistributions.testDistributionFunctions#Output.MayIgnoreWarningContext#
+#pgamma(0, 0,  scale=2)
+[1] 0
+
+##com.oracle.truffle.r.test.library.stats.TestDistributions.testDistributionFunctions#Output.MayIgnoreWarningContext#
+#pgamma(0, 1, -1)
+[1] NaN
+Warning message:
+In pgamma(0, 1, -1) : NaNs produced
+
+##com.oracle.truffle.r.test.library.stats.TestDistributions.testDistributionFunctions#Output.MayIgnoreWarningContext#
+#pgamma(0, 1, -Inf)
+[1] NaN
+Warning message:
+In pgamma(0, 1, -Inf) : NaNs produced
+
+##com.oracle.truffle.r.test.library.stats.TestDistributions.testDistributionFunctions#Output.MayIgnoreWarningContext#
+#pgamma(0, 1, 0)
+[1] 0
+
+##com.oracle.truffle.r.test.library.stats.TestDistributions.testDistributionFunctions#Output.MayIgnoreWarningContext#
+#pgamma(0, 1, Inf)
+[1] NaN
+Warning message:
+In pgamma(0, 1, Inf) : NaNs produced
+
+##com.oracle.truffle.r.test.library.stats.TestDistributions.testDistributionFunctions#Output.MayIgnoreWarningContext#
+#pgamma(0, 1, NaN)
+[1] NaN
+
+##com.oracle.truffle.r.test.library.stats.TestDistributions.testDistributionFunctions#Output.MayIgnoreWarningContext#
+#pgamma(0, Inf,  scale=2)
+[1] 0
+
+##com.oracle.truffle.r.test.library.stats.TestDistributions.testDistributionFunctions#Output.MayIgnoreWarningContext#
+#pgamma(0, NaN,  scale=2)
+[1] NaN
+
+##com.oracle.truffle.r.test.library.stats.TestDistributions.testDistributionFunctions#Output.MayIgnoreWarningContext#
+#pgamma(c(-Inf, -0.42e-30, 0, 0.42e-30, Inf, NaN), 1, scale=2, lower.tail=F, log.p=F)
+[1]   1   1   1   1   0 NaN
+
+##com.oracle.truffle.r.test.library.stats.TestDistributions.testDistributionFunctions#Output.MayIgnoreWarningContext#
+#pgamma(c(-Inf, -0.42e-30, 0, 0.42e-30, Inf, NaN), 1, scale=2, lower.tail=F, log.p=T)
+[1]  0.0e+00  0.0e+00  0.0e+00 -2.1e-31     -Inf      NaN
+
+##com.oracle.truffle.r.test.library.stats.TestDistributions.testDistributionFunctions#Output.MayIgnoreWarningContext#
+#pgamma(c(-Inf, -0.42e-30, 0, 0.42e-30, Inf, NaN), 1, scale=2, lower.tail=T, log.p=F)
+[1] 0.0e+00 0.0e+00 0.0e+00 2.1e-31 1.0e+00     NaN
+
+##com.oracle.truffle.r.test.library.stats.TestDistributions.testDistributionFunctions#Output.MayIgnoreWarningContext#
+#pgamma(c(-Inf, -0.42e-30, 0, 0.42e-30, Inf, NaN), 1, scale=2, lower.tail=T, log.p=T)
+[1]     -Inf     -Inf     -Inf -70.6382   0.0000      NaN
+
+##com.oracle.truffle.r.test.library.stats.TestDistributions.testDistributionFunctions#Output.MayIgnoreWarningContext#
+#pgamma(c(900, 5000, 0), 11e11, scale=23e-11, lower.tail=F, log.p=F)
+[1] 0 0 1
+
+##com.oracle.truffle.r.test.library.stats.TestDistributions.testDistributionFunctions#Output.MayIgnoreWarningContext#
+#pgamma(c(900, 5000, 0), 11e11, scale=23e-11, lower.tail=F, log.p=T)
+[1] -1.417138e+12 -1.735695e+13  0.000000e+00
+
+##com.oracle.truffle.r.test.library.stats.TestDistributions.testDistributionFunctions#Output.MayIgnoreWarningContext#
+#pgamma(c(900, 5000, 0), 11e11, scale=23e-11, lower.tail=T, log.p=F)
+[1] 1 1 0
+
+##com.oracle.truffle.r.test.library.stats.TestDistributions.testDistributionFunctions#Output.MayIgnoreWarningContext#
+#pgamma(c(900, 5000, 0), 11e11, scale=23e-11, lower.tail=T, log.p=T)
+[1]    0    0 -Inf
+
+##com.oracle.truffle.r.test.library.stats.TestDistributions.testDistributionFunctions#Output.MayIgnoreWarningContext#
+#phyper(0, -10,  11,  4)
+[1] NaN
+Warning message:
+In phyper(0, -10, 11, 4) : NaNs produced
+
+##com.oracle.truffle.r.test.library.stats.TestDistributions.testDistributionFunctions#Output.MayIgnoreWarningContext#
+#phyper(0, -Inf,  11,  4)
+[1] NaN
+Warning message:
+In phyper(0, -Inf, 11, 4) : NaNs produced
+
+##com.oracle.truffle.r.test.library.stats.TestDistributions.testDistributionFunctions#Output.MayIgnoreWarningContext#
+#phyper(0, 0.3,  11,  4)
+[1] 1
+
+##com.oracle.truffle.r.test.library.stats.TestDistributions.testDistributionFunctions#Output.MayIgnoreWarningContext#
+#phyper(0, 7,  11, -10)
+[1] NaN
+Warning message:
+In phyper(0, 7, 11, -10) : NaNs produced
+
+##com.oracle.truffle.r.test.library.stats.TestDistributions.testDistributionFunctions#Output.MayIgnoreWarningContext#
+#phyper(0, 7,  11, -Inf)
+[1] NaN
+Warning message:
+In phyper(0, 7, 11, -Inf) : NaNs produced
+
+##com.oracle.truffle.r.test.library.stats.TestDistributions.testDistributionFunctions#Output.MayIgnoreWarningContext#
+#phyper(0, 7,  11, 0.3)
+[1] 1
+
+##com.oracle.truffle.r.test.library.stats.TestDistributions.testDistributionFunctions#Output.MayIgnoreWarningContext#
+#phyper(0, 7,  11, Inf)
+[1] NaN
+Warning message:
+In phyper(0, 7, 11, Inf) : NaNs produced
+
+##com.oracle.truffle.r.test.library.stats.TestDistributions.testDistributionFunctions#Output.MayIgnoreWarningContext#
+#phyper(0, 7,  11, NaN)
+[1] NaN
+
+##com.oracle.truffle.r.test.library.stats.TestDistributions.testDistributionFunctions#Output.MayIgnoreWarningContext#
+#phyper(0, 7, -10,  4)
+[1] NaN
+Warning message:
+In phyper(0, 7, -10, 4) : NaNs produced
+
+##com.oracle.truffle.r.test.library.stats.TestDistributions.testDistributionFunctions#Output.MayIgnoreWarningContext#
+#phyper(0, 7, -Inf,  4)
+[1] NaN
+Warning message:
+In phyper(0, 7, -Inf, 4) : NaNs produced
+
+##com.oracle.truffle.r.test.library.stats.TestDistributions.testDistributionFunctions#Output.MayIgnoreWarningContext#
+#phyper(0, 7, 0.3,  4)
+[1] 0
+
+##com.oracle.truffle.r.test.library.stats.TestDistributions.testDistributionFunctions#Output.MayIgnoreWarningContext#
+#phyper(0, 7, Inf,  4)
+[1] NaN
+Warning message:
+In phyper(0, 7, Inf, 4) : NaNs produced
+
+##com.oracle.truffle.r.test.library.stats.TestDistributions.testDistributionFunctions#Output.MayIgnoreWarningContext#
+#phyper(0, 7, NaN,  4)
+[1] NaN
+
+##com.oracle.truffle.r.test.library.stats.TestDistributions.testDistributionFunctions#Output.MayIgnoreWarningContext#
+#phyper(0, Inf,  11,  4)
+[1] NaN
+Warning message:
+In phyper(0, Inf, 11, 4) : NaNs produced
+
+##com.oracle.truffle.r.test.library.stats.TestDistributions.testDistributionFunctions#Output.MayIgnoreWarningContext#
+#phyper(0, NaN,  11,  4)
+[1] NaN
+
+##com.oracle.truffle.r.test.library.stats.TestDistributions.testDistributionFunctions#Output.MayIgnoreWarningContext#
+#phyper(c(0.1, -Inf, Inf, 0.3e89), 5, 5, 5, lower.tail=F, log.p=F)
+[1] 0.9960317 1.0000000 0.0000000 0.0000000
+
+##com.oracle.truffle.r.test.library.stats.TestDistributions.testDistributionFunctions#Output.MayIgnoreWarningContext#
+#phyper(c(0.1, -Inf, Inf, 0.3e89), 5, 5, 5, lower.tail=F, log.p=T)
+[1] -0.003976148  0.000000000         -Inf         -Inf
+
+##com.oracle.truffle.r.test.library.stats.TestDistributions.testDistributionFunctions#Output.MayIgnoreWarningContext#
+#phyper(c(0.1, -Inf, Inf, 0.3e89), 5, 5, 5, lower.tail=T, log.p=F)
+[1] 0.003968254 0.000000000 1.000000000 1.000000000
+
+##com.oracle.truffle.r.test.library.stats.TestDistributions.testDistributionFunctions#Output.MayIgnoreWarningContext#
+#phyper(c(0.1, -Inf, Inf, 0.3e89), 5, 5, 5, lower.tail=T, log.p=T)
+[1] -5.529429      -Inf  0.000000  0.000000
+
+##com.oracle.truffle.r.test.library.stats.TestDistributions.testDistributionFunctions#Output.MayIgnoreWarningContext#
+#phyper(c(1, 2, 3, 4, 20, 12e12), 7, 11, 4, lower.tail=F, log.p=F)
+[1] 0.51470588 0.13725490 0.01143791 0.00000000 0.00000000 0.00000000
+
+##com.oracle.truffle.r.test.library.stats.TestDistributions.testDistributionFunctions#Output.MayIgnoreWarningContext#
+#phyper(c(1, 2, 3, 4, 20, 12e12), 7, 11, 4, lower.tail=F, log.p=T)
+[1] -0.6641596 -1.9859155 -4.4708221       -Inf       -Inf       -Inf
+
+##com.oracle.truffle.r.test.library.stats.TestDistributions.testDistributionFunctions#Output.MayIgnoreWarningContext#
+#phyper(c(1, 2, 3, 4, 20, 12e12), 7, 11, 4, lower.tail=T, log.p=F)
+[1] 0.4852941 0.8627451 0.9885621 1.0000000 1.0000000 1.0000000
+
+##com.oracle.truffle.r.test.library.stats.TestDistributions.testDistributionFunctions#Output.MayIgnoreWarningContext#
+#phyper(c(1, 2, 3, 4, 20, 12e12), 7, 11, 4, lower.tail=T, log.p=T)
+[1] -0.72300014 -0.14763600 -0.01150382  0.00000000  0.00000000  0.00000000
+
+##com.oracle.truffle.r.test.library.stats.TestDistributions.testDistributionFunctions#Output.MayIgnoreWarningContext#
+#phyper(c(1, 2, 3, 4, 20, 12e12), 7e12, 11, 4, lower.tail=F, log.p=F)
+[1] 1 1 1 0 0 0
+
+##com.oracle.truffle.r.test.library.stats.TestDistributions.testDistributionFunctions#Output.MayIgnoreWarningContext#
+#phyper(c(1, 2, 3, 4, 20, 12e12), 7e12, 11, 4, lower.tail=F, log.p=T)
+[1] -1.154519e-35 -1.346939e-23 -6.285714e-12          -Inf          -Inf
+[6]          -Inf
+
+##com.oracle.truffle.r.test.library.stats.TestDistributions.testDistributionFunctions#Output.MayIgnoreWarningContext#
+#phyper(c(1, 2, 3, 4, 20, 12e12), 7e12, 11, 4, lower.tail=T, log.p=F)
+[1] 1.154519e-35 1.346939e-23 6.285714e-12 1.000000e+00 1.000000e+00
+[6] 1.000000e+00
+
+##com.oracle.truffle.r.test.library.stats.TestDistributions.testDistributionFunctions#Output.MayIgnoreWarningContext#
+#phyper(c(1, 2, 3, 4, 20, 12e12), 7e12, 11, 4, lower.tail=T, log.p=T)
+[1] -80.44679 -52.66162 -25.79274   0.00000   0.00000   0.00000
+
+##com.oracle.truffle.r.test.library.stats.TestDistributions.testDistributionFunctions#Output.MayIgnoreWarningContext#
+#phyper(c(1, 2, 3, 4, 5, 6, 7, 8, 11, 20, 12e12), 7, 11, 12, lower.tail=F, log.p=F)
+ [1] 0.99962293 0.98717949 0.88348416 0.57239819 0.19909502 0.02488688
+ [7] 0.00000000 0.00000000 0.00000000 0.00000000 0.00000000
+
+##com.oracle.truffle.r.test.library.stats.TestDistributions.testDistributionFunctions#Output.MayIgnoreWarningContext#
+#phyper(c(1, 2, 3, 4, 5, 6, 7, 8, 11, 20, 12e12), 7, 11, 12, lower.tail=F, log.p=T)
+ [1] -0.000377145 -0.012903405 -0.123881913 -0.557920393 -1.613973068
+ [6] -3.693414609         -Inf         -Inf         -Inf         -Inf
+[11]         -Inf
+
+##com.oracle.truffle.r.test.library.stats.TestDistributions.testDistributionFunctions#Output.MayIgnoreWarningContext#
+#phyper(c(1, 2, 3, 4, 5, 6, 7, 8, 11, 20, 12e12), 7, 11, 12, lower.tail=T, log.p=F)
+ [1] 0.0003770739 0.0128205128 0.1165158371 0.4276018100 0.8009049774
+ [6] 0.9751131222 1.0000000000 1.0000000000 1.0000000000 1.0000000000
+[11] 1.0000000000
+
+##com.oracle.truffle.r.test.library.stats.TestDistributions.testDistributionFunctions#Output.MayIgnoreWarningContext#
+#phyper(c(1, 2, 3, 4, 5, 6, 7, 8, 11, 20, 12e12), 7, 11, 12, lower.tail=T, log.p=T)
+ [1] -7.88306935 -4.35670883 -2.14972807 -0.84956287 -0.22201297 -0.02520179
+ [7]  0.00000000  0.00000000  0.00000000  0.00000000  0.00000000
+
+##com.oracle.truffle.r.test.library.stats.TestDistributions.testDistributionFunctions#Output.MayIgnoreWarningContext#
+#phyper(c(1, 2, 3, 7, 20, 12e12), 11, 7e12, 7, lower.tail=F, log.p=F)
+[1] 4.714286e-23 1.010204e-34 1.154519e-46 0.000000e+00 0.000000e+00
+[6] 0.000000e+00
+
+##com.oracle.truffle.r.test.library.stats.TestDistributions.testDistributionFunctions#Output.MayIgnoreWarningContext#
+#phyper(c(1, 2, 3, 7, 20, 12e12), 11, 7e12, 7, lower.tail=F, log.p=T)
+[1]  -51.40886  -78.27774 -105.77523       -Inf       -Inf       -Inf
+
+##com.oracle.truffle.r.test.library.stats.TestDistributions.testDistributionFunctions#Output.MayIgnoreWarningContext#
+#phyper(c(1, 2, 3, 7, 20, 12e12), 11, 7e12, 7, lower.tail=T, log.p=F)
+[1] 1 1 1 1 1 1
+
+##com.oracle.truffle.r.test.library.stats.TestDistributions.testDistributionFunctions#Output.MayIgnoreWarningContext#
+#phyper(c(1, 2, 3, 7, 20, 12e12), 11, 7e12, 7, lower.tail=T, log.p=T)
+[1] -4.714286e-23 -1.010204e-34 -1.154519e-46  0.000000e+00  0.000000e+00
+[6]  0.000000e+00
+
+##com.oracle.truffle.r.test.library.stats.TestDistributions.testDistributionFunctions#Output.MayIgnoreWarningContext#
+#phyper(c(2), 3, 4, 10, lower.tail=F, log.p=F)
+[1] NaN
+Warning message:
+In phyper(c(2), 3, 4, 10, lower.tail = F, log.p = F) : NaNs produced
+
+##com.oracle.truffle.r.test.library.stats.TestDistributions.testDistributionFunctions#Output.MayIgnoreWarningContext#
+#phyper(c(2), 3, 4, 10, lower.tail=F, log.p=T)
+[1] NaN
+Warning message:
+In phyper(c(2), 3, 4, 10, lower.tail = F, log.p = T) : NaNs produced
+
+##com.oracle.truffle.r.test.library.stats.TestDistributions.testDistributionFunctions#Output.MayIgnoreWarningContext#
+#phyper(c(2), 3, 4, 10, lower.tail=T, log.p=F)
+[1] NaN
+Warning message:
+In phyper(c(2), 3, 4, 10, lower.tail = T, log.p = F) : NaNs produced
+
+##com.oracle.truffle.r.test.library.stats.TestDistributions.testDistributionFunctions#Output.MayIgnoreWarningContext#
+#phyper(c(2), 3, 4, 10, lower.tail=T, log.p=T)
+[1] NaN
+Warning message:
+In phyper(c(2), 3, 4, 10, lower.tail = T, log.p = T) : NaNs produced
+
+##com.oracle.truffle.r.test.library.stats.TestDistributions.testDistributionFunctions#Output.MayIgnoreWarningContext#
+#pnorm(0, -Inf,  -1)
+[1] NaN
+Warning message:
+In pnorm(0, -Inf, -1) : NaNs produced
+
+##com.oracle.truffle.r.test.library.stats.TestDistributions.testDistributionFunctions#Output.MayIgnoreWarningContext#
+#pnorm(0, 0, -Inf)
+[1] NaN
+Warning message:
+In pnorm(0, 0, -Inf) : NaNs produced
+
+##com.oracle.truffle.r.test.library.stats.TestDistributions.testDistributionFunctions#Output.MayIgnoreWarningContext#
+#pnorm(0, 0, Inf)
+[1] 0.5
+
+##com.oracle.truffle.r.test.library.stats.TestDistributions.testDistributionFunctions#Output.MayIgnoreWarningContext#
+#pnorm(0, 0, NaN)
+[1] NaN
+
+##com.oracle.truffle.r.test.library.stats.TestDistributions.testDistributionFunctions#Output.MayIgnoreWarningContext#
+#pnorm(0, Inf,  -1)
+[1] NaN
+Warning message:
+In pnorm(0, Inf, -1) : NaNs produced
+
+##com.oracle.truffle.r.test.library.stats.TestDistributions.testDistributionFunctions#Output.MayIgnoreWarningContext#
+#pnorm(0, NaN,  -1)
+[1] NaN
+
+##com.oracle.truffle.r.test.library.stats.TestDistributions.testDistributionFunctions#Output.MayIgnoreWarningContext#
+#pnorm(c(0), 0, -1, lower.tail=F, log.p=F)
+[1] NaN
+Warning message:
+In pnorm(c(0), 0, -1, lower.tail = F, log.p = F) : NaNs produced
+
+##com.oracle.truffle.r.test.library.stats.TestDistributions.testDistributionFunctions#Output.MayIgnoreWarningContext#
+#pnorm(c(0), 0, -1, lower.tail=F, log.p=T)
+[1] NaN
+Warning message:
+In pnorm(c(0), 0, -1, lower.tail = F, log.p = T) : NaNs produced
+
+##com.oracle.truffle.r.test.library.stats.TestDistributions.testDistributionFunctions#Output.MayIgnoreWarningContext#
+#pnorm(c(0), 0, -1, lower.tail=T, log.p=F)
+[1] NaN
+Warning message:
+In pnorm(c(0), 0, -1, lower.tail = T, log.p = F) : NaNs produced
+
+##com.oracle.truffle.r.test.library.stats.TestDistributions.testDistributionFunctions#Output.MayIgnoreWarningContext#
+#pnorm(c(0), 0, -1, lower.tail=T, log.p=T)
+[1] NaN
+Warning message:
+In pnorm(c(0), 0, -1, lower.tail = T, log.p = T) : NaNs produced
+
+##com.oracle.truffle.r.test.library.stats.TestDistributions.testDistributionFunctions#Output.MayIgnoreWarningContext#
+#pnorm(c(1, -Inf, -0.42e-30, 0, 0.42e-30, Inf, NaN), 0, 0, lower.tail=F, log.p=F)
+[1]   0   1   1   0   0   0 NaN
+
+##com.oracle.truffle.r.test.library.stats.TestDistributions.testDistributionFunctions#Output.MayIgnoreWarningContext#
+#pnorm(c(1, -Inf, -0.42e-30, 0, 0.42e-30, Inf, NaN), 0, 0, lower.tail=F, log.p=T)
+[1] -Inf    0    0 -Inf -Inf -Inf  NaN
+
+##com.oracle.truffle.r.test.library.stats.TestDistributions.testDistributionFunctions#Output.MayIgnoreWarningContext#
+#pnorm(c(1, -Inf, -0.42e-30, 0, 0.42e-30, Inf, NaN), 0, 0, lower.tail=T, log.p=F)
+[1]   1   0   0   1   1   1 NaN
+
+##com.oracle.truffle.r.test.library.stats.TestDistributions.testDistributionFunctions#Output.MayIgnoreWarningContext#
+#pnorm(c(1, -Inf, -0.42e-30, 0, 0.42e-30, Inf, NaN), 0, 0, lower.tail=T, log.p=T)
+[1]    0 -Inf -Inf    0    0    0  NaN
+
+##com.oracle.truffle.r.test.library.stats.TestDistributions.testDistributionFunctions#Output.MayIgnoreWarningContext#
+#pnorm(c(4, -100, 0), 4, 4, lower.tail=F, log.p=F)
+[1] 0.5000000 1.0000000 0.8413447
+
+##com.oracle.truffle.r.test.library.stats.TestDistributions.testDistributionFunctions#Output.MayIgnoreWarningContext#
+#pnorm(c(4, -100, 0), 4, 4, lower.tail=F, log.p=T)
+[1]  -6.931472e-01 -2.476063e-149  -1.727538e-01
+
+##com.oracle.truffle.r.test.library.stats.TestDistributions.testDistributionFunctions#Output.MayIgnoreWarningContext#
+#pnorm(c(4, -100, 0), 4, 4, lower.tail=T, log.p=F)
+[1]  5.000000e-01 2.476063e-149  1.586553e-01
+
+##com.oracle.truffle.r.test.library.stats.TestDistributions.testDistributionFunctions#Output.MayIgnoreWarningContext#
+#pnorm(c(4, -100, 0), 4, 4, lower.tail=T, log.p=T)
+[1]   -0.6931472 -342.1785089   -1.8410216
+
+##com.oracle.truffle.r.test.library.stats.TestDistributions.testDistributionFunctions#Output.MayIgnoreWarningContext#
+#punif(0, -3, -Inf)
+[1] NaN
+Warning message:
+In punif(0, -3, -Inf) : NaNs produced
+
+##com.oracle.truffle.r.test.library.stats.TestDistributions.testDistributionFunctions#Output.MayIgnoreWarningContext#
+#punif(0, -3, Inf)
+[1] NaN
+Warning message:
+In punif(0, -3, Inf) : NaNs produced
+
+##com.oracle.truffle.r.test.library.stats.TestDistributions.testDistributionFunctions#Output.MayIgnoreWarningContext#
+#punif(0, -3, NaN)
+[1] NaN
+
+##com.oracle.truffle.r.test.library.stats.TestDistributions.testDistributionFunctions#Output.MayIgnoreWarningContext#
+#punif(0, -Inf,  3.3)
+[1] NaN
+Warning message:
+In punif(0, -Inf, 3.3) : NaNs produced
+
+##com.oracle.truffle.r.test.library.stats.TestDistributions.testDistributionFunctions#Output.MayIgnoreWarningContext#
+#punif(0, Inf,  3.3)
+[1] NaN
+Warning message:
+In punif(0, Inf, 3.3) : NaNs produced
+
+##com.oracle.truffle.r.test.library.stats.TestDistributions.testDistributionFunctions#Output.MayIgnoreWarningContext#
+#punif(0, NaN,  3.3)
+[1] NaN
+
+##com.oracle.truffle.r.test.library.stats.TestDistributions.testDistributionFunctions#Output.MayIgnoreWarningContext#
+#punif(c(-3, 2, 3.3, -Inf, -0.42e-30, 0, 0.42e-30, Inf, NaN), -3, 3.3, lower.tail=F, log.p=F)
+[1] 1.0000000 0.2063492 0.0000000 1.0000000 0.5238095 0.5238095 0.5238095
+[8] 0.0000000       NaN
+
+##com.oracle.truffle.r.test.library.stats.TestDistributions.testDistributionFunctions#Output.MayIgnoreWarningContext#
+#punif(c(-3, 2, 3.3, -Inf, -0.42e-30, 0, 0.42e-30, Inf, NaN), -3, 3.3, lower.tail=F, log.p=T)
+[1]  0.0000000 -1.5781854       -Inf  0.0000000 -0.6466272 -0.6466272 -0.6466272
+[8]       -Inf        NaN
+
+##com.oracle.truffle.r.test.library.stats.TestDistributions.testDistributionFunctions#Output.MayIgnoreWarningContext#
+#punif(c(-3, 2, 3.3, -Inf, -0.42e-30, 0, 0.42e-30, Inf, NaN), -3, 3.3, lower.tail=T, log.p=F)
+[1] 0.0000000 0.7936508 1.0000000 0.0000000 0.4761905 0.4761905 0.4761905
+[8] 1.0000000       NaN
+
+##com.oracle.truffle.r.test.library.stats.TestDistributions.testDistributionFunctions#Output.MayIgnoreWarningContext#
+#punif(c(-3, 2, 3.3, -Inf, -0.42e-30, 0, 0.42e-30, Inf, NaN), -3, 3.3, lower.tail=T, log.p=T)
+[1]       -Inf -0.2311117  0.0000000       -Inf -0.7419373 -0.7419373 -0.7419373
+[8]  0.0000000        NaN
+
+##com.oracle.truffle.r.test.library.stats.TestDistributions.testQuantileFunctions#Output.MayIgnoreWarningContext#
+#qbeta(-0.42e-38, 0.5, 0.5)
+[1] NaN
+Warning message:
+In qbeta(-4.2e-39, 0.5, 0.5) : NaNs produced
+
+##com.oracle.truffle.r.test.library.stats.TestDistributions.testQuantileFunctions#Output.MayIgnoreWarningContext#
+#qbeta(-0.42e-38, 10, 15, 0)
+[1] NaN
+Warning message:
+In qbeta(-4.2e-39, 10, 15, 0) : NaNs produced
+
+##com.oracle.truffle.r.test.library.stats.TestDistributions.testQuantileFunctions#Output.MayIgnoreWarningContext#
+#qbeta(-42, 0.5, 0.5)
+[1] NaN
+Warning message:
+In qbeta(-42, 0.5, 0.5) : NaNs produced
+
+##com.oracle.truffle.r.test.library.stats.TestDistributions.testQuantileFunctions#Output.MayIgnoreWarningContext#
+#qbeta(-42, 10, 15, 0)
+[1] NaN
+Warning message:
+In qbeta(-42, 10, 15, 0) : NaNs produced
+
+##com.oracle.truffle.r.test.library.stats.TestDistributions.testQuantileFunctions#Output.MayIgnoreWarningContext#
+#qbeta(-Inf, 0.5, 0.5)
+[1] NaN
+Warning message:
+In qbeta(-Inf, 0.5, 0.5) : NaNs produced
+
+##com.oracle.truffle.r.test.library.stats.TestDistributions.testQuantileFunctions#Output.MayIgnoreWarningContext#
+#qbeta(-Inf, 10, 15, 0)
+[1] NaN
+Warning message:
+In qbeta(-Inf, 10, 15, 0) : NaNs produced
+
+##com.oracle.truffle.r.test.library.stats.TestDistributions.testQuantileFunctions#Output.MayIgnoreWarningContext#
+#qbeta(0, -1,  0.5)
+[1] NaN
+Warning message:
+In qbeta(0, -1, 0.5) : NaNs produced
+
+##com.oracle.truffle.r.test.library.stats.TestDistributions.testQuantileFunctions#Output.MayIgnoreWarningContext#
+#qbeta(0, -4,  15,  0)
+[1] NaN
+Warning message:
+In qbeta(0, -4, 15, 0) : NaNs produced
+
+##com.oracle.truffle.r.test.library.stats.TestDistributions.testQuantileFunctions#Output.MayIgnoreWarningContext#
+#qbeta(0, -Inf,  0.5)
+[1] NaN
+Warning message:
+In qbeta(0, -Inf, 0.5) : NaNs produced
+
+##com.oracle.truffle.r.test.library.stats.TestDistributions.testQuantileFunctions#Output.MayIgnoreWarningContext#
+#qbeta(0, -Inf,  15,  0)
+[1] NaN
+Warning message:
+In qbeta(0, -Inf, 15, 0) : NaNs produced
+
+##com.oracle.truffle.r.test.library.stats.TestDistributions.testQuantileFunctions#Output.MayIgnoreWarningContext#
+#qbeta(0, 0,  0.5)
+[1] 0
+
+##com.oracle.truffle.r.test.library.stats.TestDistributions.testQuantileFunctions#Output.MayIgnoreWarningContext#
+#qbeta(0, 0,  15,  0)
+[1] NaN
+Warning message:
+In qbeta(0, 0, 15, 0) : NaNs produced
+
+##com.oracle.truffle.r.test.library.stats.TestDistributions.testQuantileFunctions#Output.MayIgnoreWarningContext#
+#qbeta(0, 0.5, -1)
+[1] NaN
+Warning message:
+In qbeta(0, 0.5, -1) : NaNs produced
+
+##com.oracle.truffle.r.test.library.stats.TestDistributions.testQuantileFunctions#Output.MayIgnoreWarningContext#
+#qbeta(0, 0.5, -Inf)
+[1] NaN
+Warning message:
+In qbeta(0, 0.5, -Inf) : NaNs produced
+
+##com.oracle.truffle.r.test.library.stats.TestDistributions.testQuantileFunctions#Output.MayIgnoreWarningContext#
+#qbeta(0, 0.5, 0)
+[1] 0
+
+##com.oracle.truffle.r.test.library.stats.TestDistributions.testQuantileFunctions#Output.MayIgnoreWarningContext#
+#qbeta(0, 0.5, Inf)
+[1] 0
+
+##com.oracle.truffle.r.test.library.stats.TestDistributions.testQuantileFunctions#Output.MayIgnoreWarningContext#
+#qbeta(0, 0.5, NaN)
+[1] NaN
+
+##com.oracle.truffle.r.test.library.stats.TestDistributions.testQuantileFunctions#Output.MayIgnoreWarningContext#
+#qbeta(0, 10,  15, -4)
+[1] NaN
+Warning message:
+In qbeta(0, 10, 15, -4) : NaNs produced
+
+##com.oracle.truffle.r.test.library.stats.TestDistributions.testQuantileFunctions#Output.MayIgnoreWarningContext#
+#qbeta(0, 10,  15, -Inf)
+[1] NaN
+Warning message:
+In qbeta(0, 10, 15, -Inf) : NaNs produced
+
+##com.oracle.truffle.r.test.library.stats.TestDistributions.testQuantileFunctions#Output.MayIgnoreWarningContext#
+#qbeta(0, 10,  15, 0)
+[1] 0
+
+##com.oracle.truffle.r.test.library.stats.TestDistributions.testQuantileFunctions#Output.MayIgnoreWarningContext#
+#qbeta(0, 10,  15, Inf)
+[1] 0
+
+##com.oracle.truffle.r.test.library.stats.TestDistributions.testQuantileFunctions#Output.MayIgnoreWarningContext#
+#qbeta(0, 10,  15, NaN)
+[1] NaN
+
+##com.oracle.truffle.r.test.library.stats.TestDistributions.testQuantileFunctions#Output.MayIgnoreWarningContext#
+#qbeta(0, 10, -4,  0)
+[1] NaN
+Warning message:
+In qbeta(0, 10, -4, 0) : NaNs produced
+
+##com.oracle.truffle.r.test.library.stats.TestDistributions.testQuantileFunctions#Output.MayIgnoreWarningContext#
+#qbeta(0, 10, -Inf,  0)
+[1] NaN
+Warning message:
+In qbeta(0, 10, -Inf, 0) : NaNs produced
+
+##com.oracle.truffle.r.test.library.stats.TestDistributions.testQuantileFunctions#Output.MayIgnoreWarningContext#
+#qbeta(0, 10, 0,  0)
+[1] NaN
+Warning message:
+In qbeta(0, 10, 0, 0) : NaNs produced
+
+##com.oracle.truffle.r.test.library.stats.TestDistributions.testQuantileFunctions#Output.MayIgnoreWarningContext#
+#qbeta(0, 10, Inf,  0)
+[1] 0
+
+##com.oracle.truffle.r.test.library.stats.TestDistributions.testQuantileFunctions#Output.MayIgnoreWarningContext#
+#qbeta(0, 10, NaN,  0)
+[1] NaN
+
+##com.oracle.truffle.r.test.library.stats.TestDistributions.testQuantileFunctions#Output.MayIgnoreWarningContext#
+#qbeta(0, Inf,  0.5)
+[1] 0
+
+##com.oracle.truffle.r.test.library.stats.TestDistributions.testQuantileFunctions#Output.MayIgnoreWarningContext#
+#qbeta(0, Inf,  15,  0)
+[1] NaN
+Warning message:
+In qbeta(0, Inf, 15, 0) : NaNs produced
+
+##com.oracle.truffle.r.test.library.stats.TestDistributions.testQuantileFunctions#Output.MayIgnoreWarningContext#
+#qbeta(0, NaN,  0.5)
+[1] NaN
+
+##com.oracle.truffle.r.test.library.stats.TestDistributions.testQuantileFunctions#Output.MayIgnoreWarningContext#
+#qbeta(0, NaN,  15,  0)
+[1] NaN
+
+##com.oracle.truffle.r.test.library.stats.TestDistributions.testQuantileFunctions#Output.MayIgnoreWarningContext#
+#qbeta(Inf, 0.5, 0.5)
+[1] NaN
+Warning message:
+In qbeta(Inf, 0.5, 0.5) : NaNs produced
+
+##com.oracle.truffle.r.test.library.stats.TestDistributions.testQuantileFunctions#Output.MayIgnoreWarningContext#
+#qbeta(Inf, 10, 15, 0)
+[1] NaN
+Warning message:
+In qbeta(Inf, 10, 15, 0) : NaNs produced
+
+##com.oracle.truffle.r.test.library.stats.TestDistributions.testQuantileFunctions#Output.MayIgnoreWarningContext#
+#qbeta(NaN, 0.5, 0.5)
+[1] NaN
+
+##com.oracle.truffle.r.test.library.stats.TestDistributions.testQuantileFunctions#Output.MayIgnoreWarningContext#
+#qbeta(NaN, 10, 15, 0)
+[1] NaN
+
+##com.oracle.truffle.r.test.library.stats.TestDistributions.testQuantileFunctions#Output.MayIgnoreWarningContext#
+#qbeta(c(0, 42e-80, 0.1, 0.5, 0.7, 1-42e-80, 1), 0, 0, lower.tail=F, log.p=F)
+[1] 1.0 0.0 0.0 0.5 1.0 0.0 0.0
+
+##com.oracle.truffle.r.test.library.stats.TestDistributions.testQuantileFunctions#Output.MayIgnoreWarningContext#
+#qbeta(c(0, 42e-80, 0.1, 0.5, 0.7, 1-42e-80, 1), 0, 0, lower.tail=T, log.p=F)
+[1] 0.0 0.0 0.0 0.5 1.0 1.0 1.0
+
+##com.oracle.truffle.r.test.library.stats.TestDistributions.testQuantileFunctions#Output.MayIgnoreWarningContext#
+#qbeta(c(0, 42e-80, 0.1, 0.5, 0.7, 1-42e-80, 1), 0, Inf, lower.tail=F, log.p=F)
+[1] 1 0 0 0 0 0 0
+
+##com.oracle.truffle.r.test.library.stats.TestDistributions.testQuantileFunctions#Output.MayIgnoreWarningContext#
+#qbeta(c(0, 42e-80, 0.1, 0.5, 0.7, 1-42e-80, 1), 0, Inf, lower.tail=T, log.p=F)
+[1] 0 0 0 0 0 1 1
+
+##com.oracle.truffle.r.test.library.stats.TestDistributions.testQuantileFunctions#Output.MayIgnoreWarningContext#
+#qbeta(c(0, 42e-80, 0.1, 0.5, 0.7, 1-42e-80, 1), 0.1, 3, lower.tail=F, log.p=F)
+[1] 1.000000e+00 1.000000e+00 9.839300e-02 2.312399e-04 1.397635e-06
+[6] 0.000000e+00 0.000000e+00
+
+##com.oracle.truffle.r.test.library.stats.TestDistributions.testQuantileFunctions#Output.MayIgnoreWarningContext#
+#qbeta(c(0, 42e-80, 0.1, 0.5, 0.7, 1-42e-80, 1), 0.1, 3, lower.tail=T, log.p=F)
+[1] 0.000000e+00 0.000000e+00 2.366901e-11 2.312399e-04 6.768603e-03
+[6] 1.000000e+00 1.000000e+00
+
+##com.oracle.truffle.r.test.library.stats.TestDistributions.testQuantileFunctions#Output.MayIgnoreWarningContext#
+#qbeta(c(0, 42e-80, 0.1, 0.5, 0.7, 1-42e-80, 1), 0.5, 0.5, lower.tail=F, log.p=F)
+[1] 1.0000000 1.0000000 0.9755283 0.5000000 0.2061074 0.0000000 0.0000000
+
+##com.oracle.truffle.r.test.library.stats.TestDistributions.testQuantileFunctions#Output.MayIgnoreWarningContext#
+#qbeta(c(0, 42e-80, 0.1, 0.5, 0.7, 1-42e-80, 1), 0.5, 0.5, lower.tail=T, log.p=F)
+[1]  0.000000e+00 4.352496e-157  2.447174e-02  5.000000e-01  7.938926e-01
+[6]  1.000000e+00  1.000000e+00
+
+##com.oracle.truffle.r.test.library.stats.TestDistributions.testQuantileFunctions#Output.MayIgnoreWarningContext#
+#qbeta(c(0, 42e-80, 0.1, 0.5, 0.7, 1-42e-80, 1), 10, 15, 0, lower.tail=F, log.p=F)
+[1] 1.0000000 1.0000000 0.5264118 0.3972924 0.3463781 0.0000000 0.0000000
+
+##com.oracle.truffle.r.test.library.stats.TestDistributions.testQuantileFunctions#Output.MayIgnoreWarningContext#
+#qbeta(c(0, 42e-80, 0.1, 0.5, 0.7, 1-42e-80, 1), 10, 15, 0, lower.tail=T, log.p=F)
+[1] 0.000000e+00 3.412491e-09 2.772130e-01 3.972924e-01 4.497463e-01
+[6] 1.000000e+00 1.000000e+00
+
+##com.oracle.truffle.r.test.library.stats.TestDistributions.testQuantileFunctions#Output.MayIgnoreWarningContext#
+#qbeta(c(0, 42e-80, 0.1, 0.5, 0.7, 1-42e-80, 1), 2, 5, lower.tail=F, log.p=F)
+[1] 1.0000000 1.0000000 0.5103163 0.2644500 0.1818035 0.0000000 0.0000000
+
+##com.oracle.truffle.r.test.library.stats.TestDistributions.testQuantileFunctions#Output.MayIgnoreWarningContext#
+#qbeta(c(0, 42e-80, 0.1, 0.5, 0.7, 1-42e-80, 1), 2, 5, lower.tail=T, log.p=F)
+[1] 0.000000e+00 1.673320e-40 9.259526e-02 2.644500e-01 3.603577e-01
+[6] 1.000000e+00 1.000000e+00
+
+##com.oracle.truffle.r.test.library.stats.TestDistributions.testQuantileFunctions#Output.MayIgnoreWarningContext#
+#qbeta(c(0, 42e-80, 0.1, 0.5, 0.7, 1-42e-80, 1), 6, 3, lower.tail=F, log.p=F)
+[1] 1.0000000 1.0000000 0.8531451 0.6794810 0.5925411 0.0000000 0.0000000
+
+##com.oracle.truffle.r.test.library.stats.TestDistributions.testQuantileFunctions#Output.MayIgnoreWarningContext#
+#qbeta(c(0, 42e-80, 0.1, 0.5, 0.7, 1-42e-80, 1), 6, 3, lower.tail=T, log.p=F)
+[1] 0.000000e+00 4.966097e-14 4.617846e-01 6.794810e-01 7.586657e-01
+[6] 1.000000e+00 1.000000e+00
+
+##com.oracle.truffle.r.test.library.stats.TestDistributions.testQuantileFunctions#Output.MayIgnoreWarningContext#
+#qbeta(c(0, 42e-80, 0.1, 0.5, 0.7, 1-42e-80, 1), 7, 11, 0.37e-10, lower.tail=F, log.p=F)
+[1] 1.0000000 1.0000000 0.5373549 0.3846872 0.3251782 0.0000000 0.0000000
+
+##com.oracle.truffle.r.test.library.stats.TestDistributions.testQuantileFunctions#Output.MayIgnoreWarningContext#
+#qbeta(c(0, 42e-80, 0.1, 0.5, 0.7, 1-42e-80, 1), 7, 11, 0.37e-10, lower.tail=T, log.p=F)
+[1] 0.000000e+00 1.551047e-12 2.461368e-01 3.846872e-01 4.466173e-01
+[6] 1.000000e+00 1.000000e+00
+
+##com.oracle.truffle.r.test.library.stats.TestDistributions.testQuantileFunctions#Output.MayIgnoreWarningContext#
+#qbeta(c(0, 42e-80, 0.1, 0.5, 0.7, 1-42e-80, 1), 7, 113e11, 1, lower.tail=F, log.p=F)
+[1] 1.000000e+00 1.000000e+00 9.979557e-13 6.326635e-13 5.134397e-13
+[6] 0.000000e+00 0.000000e+00
+
+##com.oracle.truffle.r.test.library.stats.TestDistributions.testQuantileFunctions#Output.MayIgnoreWarningContext#
+#qbeta(c(0, 42e-80, 0.1, 0.5, 0.7, 1-42e-80, 1), 7, 113e11, 1, lower.tail=T, log.p=F)
+[1] 0.000000e+00 2.042740e-24 3.697562e-13 6.326635e-13 7.690718e-13
+[6] 1.000000e+00 1.000000e+00
+
+##com.oracle.truffle.r.test.library.stats.TestDistributions.testQuantileFunctions#Output.MayIgnoreWarningContext#
+#qbeta(c(0, 42e-80, 0.1, 0.5, 0.7, 1-42e-80, 1), 7, 13, 3, lower.tail=F, log.p=F)
+[1] 1.0000000 1.0000000 0.5361327 0.3904742 0.3326837 0.0000000 0.0000000
+
+##com.oracle.truffle.r.test.library.stats.TestDistributions.testQuantileFunctions#Output.MayIgnoreWarningContext#
+#qbeta(c(0, 42e-80, 0.1, 0.5, 0.7, 1-42e-80, 1), 7, 13, 3, lower.tail=T, log.p=F)
+[1] 0.000000e+00 1.677349e-12 2.547294e-01 3.904742e-01 4.499427e-01
+[6] 1.000000e+00 1.000000e+00
+
+##com.oracle.truffle.r.test.library.stats.TestDistributions.testQuantileFunctions#Output.MayIgnoreWarningContext#
+#qbeta(c(0, 42e-80, 0.1, 0.5, 0.7, 1-42e-80, 1), Inf, 0, lower.tail=F, log.p=F)
+[1] 1 1 1 1 1 0 0
+
+##com.oracle.truffle.r.test.library.stats.TestDistributions.testQuantileFunctions#Output.MayIgnoreWarningContext#
+#qbeta(c(0, 42e-80, 0.1, 0.5, 0.7, 1-42e-80, 1), Inf, 0, lower.tail=T, log.p=F)
+[1] 0 1 1 1 1 1 1
+
+##com.oracle.truffle.r.test.library.stats.TestDistributions.testQuantileFunctions#Output.MayIgnoreWarningContext#
+#qbeta(log(c(0, 42e-80, 0.1, 0.5, 0.7, 1-42e-80, 1)), 0, 0, lower.tail=F, log.p=T)
+[1] 1.0 0.0 0.0 0.5 1.0 0.0 0.0
+
+##com.oracle.truffle.r.test.library.stats.TestDistributions.testQuantileFunctions#Output.MayIgnoreWarningContext#
+#qbeta(log(c(0, 42e-80, 0.1, 0.5, 0.7, 1-42e-80, 1)), 0, 0, lower.tail=T, log.p=T)
+[1] 0.0 0.0 0.0 0.5 1.0 1.0 1.0
+
+##com.oracle.truffle.r.test.library.stats.TestDistributions.testQuantileFunctions#Output.MayIgnoreWarningContext#
+#qbeta(log(c(0, 42e-80, 0.1, 0.5, 0.7, 1-42e-80, 1)), 0, Inf, lower.tail=F, log.p=T)
+[1] 1 0 0 0 0 0 0
+
+##com.oracle.truffle.r.test.library.stats.TestDistributions.testQuantileFunctions#Output.MayIgnoreWarningContext#
+#qbeta(log(c(0, 42e-80, 0.1, 0.5, 0.7, 1-42e-80, 1)), 0, Inf, lower.tail=T, log.p=T)
+[1] 0 0 0 0 0 1 1
+
+##com.oracle.truffle.r.test.library.stats.TestDistributions.testQuantileFunctions#Output.MayIgnoreWarningContext#
+#qbeta(log(c(0, 42e-80, 0.1, 0.5, 0.7, 1-42e-80, 1)), 0.1, 3, lower.tail=F, log.p=T)
+[1] 1.000000e+00 1.000000e+00 9.839300e-02 2.312399e-04 1.397635e-06
+[6] 0.000000e+00 0.000000e+00
+
+##com.oracle.truffle.r.test.library.stats.TestDistributions.testQuantileFunctions#Output.MayIgnoreWarningContext#
+#qbeta(log(c(0, 42e-80, 0.1, 0.5, 0.7, 1-42e-80, 1)), 0.1, 3, lower.tail=T, log.p=T)
+[1]  0.000000e+00 1.112537e-308  2.366901e-11  2.312399e-04  6.768603e-03
+[6]  1.000000e+00  1.000000e+00
+
+##com.oracle.truffle.r.test.library.stats.TestDistributions.testQuantileFunctions#Output.MayIgnoreWarningContext#
+#qbeta(log(c(0, 42e-80, 0.1, 0.5, 0.7, 1-42e-80, 1)), 0.5, 0.5, lower.tail=F, log.p=T)
+[1] 1.0000000 1.0000000 0.9755283 0.5000000 0.2061074 0.0000000 0.0000000
+
+##com.oracle.truffle.r.test.library.stats.TestDistributions.testQuantileFunctions#Output.MayIgnoreWarningContext#
+#qbeta(log(c(0, 42e-80, 0.1, 0.5, 0.7, 1-42e-80, 1)), 0.5, 0.5, lower.tail=T, log.p=T)
+[1]  0.000000e+00 4.352496e-157  2.447174e-02  5.000000e-01  7.938926e-01
+[6]  1.000000e+00  1.000000e+00
+
+##com.oracle.truffle.r.test.library.stats.TestDistributions.testQuantileFunctions#Output.MayIgnoreWarningContext#
+#qbeta(log(c(0, 42e-80, 0.1, 0.5, 0.7, 1-42e-80, 1)), 10, 15, 0, lower.tail=F, log.p=T)
+[1] 1.0000000 1.0000000 0.5264118 0.3972924 0.3463781 0.0000000 0.0000000
+
+##com.oracle.truffle.r.test.library.stats.TestDistributions.testQuantileFunctions#Output.MayIgnoreWarningContext#
+#qbeta(log(c(0, 42e-80, 0.1, 0.5, 0.7, 1-42e-80, 1)), 10, 15, 0, lower.tail=T, log.p=T)
+[1] 0.000000e+00 3.412491e-09 2.772130e-01 3.972924e-01 4.497463e-01
+[6] 1.000000e+00 1.000000e+00
+
+##com.oracle.truffle.r.test.library.stats.TestDistributions.testQuantileFunctions#Output.MayIgnoreWarningContext#
+#qbeta(log(c(0, 42e-80, 0.1, 0.5, 0.7, 1-42e-80, 1)), 2, 5, lower.tail=F, log.p=T)
+[1] 1.0000000 1.0000000 0.5103163 0.2644500 0.1818035 0.0000000 0.0000000
+
+##com.oracle.truffle.r.test.library.stats.TestDistributions.testQuantileFunctions#Output.MayIgnoreWarningContext#
+#qbeta(log(c(0, 42e-80, 0.1, 0.5, 0.7, 1-42e-80, 1)), 2, 5, lower.tail=T, log.p=T)
+[1] 0.000000e+00 1.673320e-40 9.259526e-02 2.644500e-01 3.603577e-01
+[6] 1.000000e+00 1.000000e+00
+
+##com.oracle.truffle.r.test.library.stats.TestDistributions.testQuantileFunctions#Output.MayIgnoreWarningContext#
+#qbeta(log(c(0, 42e-80, 0.1, 0.5, 0.7, 1-42e-80, 1)), 6, 3, lower.tail=F, log.p=T)
+[1] 1.0000000 1.0000000 0.8531451 0.6794810 0.5925411 0.0000000 0.0000000
+
+##com.oracle.truffle.r.test.library.stats.TestDistributions.testQuantileFunctions#Output.MayIgnoreWarningContext#
+#qbeta(log(c(0, 42e-80, 0.1, 0.5, 0.7, 1-42e-80, 1)), 6, 3, lower.tail=T, log.p=T)
+[1] 0.000000e+00 4.966097e-14 4.617846e-01 6.794810e-01 7.586657e-01
+[6] 1.000000e+00 1.000000e+00
+
+##com.oracle.truffle.r.test.library.stats.TestDistributions.testQuantileFunctions#Output.MayIgnoreWarningContext#
+#qbeta(log(c(0, 42e-80, 0.1, 0.5, 0.7, 1-42e-80, 1)), 7, 11, 0.37e-10, lower.tail=F, log.p=T)
+[1] 1.0000000 1.0000000 0.5373549 0.3846872 0.3251782 0.0000000 0.0000000
+
+##com.oracle.truffle.r.test.library.stats.TestDistributions.testQuantileFunctions#Output.MayIgnoreWarningContext#
+#qbeta(log(c(0, 42e-80, 0.1, 0.5, 0.7, 1-42e-80, 1)), 7, 11, 0.37e-10, lower.tail=T, log.p=T)
+[1] 0.000000e+00 1.551047e-12 2.461368e-01 3.846872e-01 4.466173e-01
+[6] 1.000000e+00 1.000000e+00
+
+##com.oracle.truffle.r.test.library.stats.TestDistributions.testQuantileFunctions#Output.MayIgnoreWarningContext#
+#qbeta(log(c(0, 42e-80, 0.1, 0.5, 0.7, 1-42e-80, 1)), 7, 113e11, 1, lower.tail=F, log.p=T)
+[1] 1.000000e+00 1.000000e+00 9.979557e-13 6.326635e-13 5.134397e-13
+[6] 0.000000e+00 0.000000e+00
+
+##com.oracle.truffle.r.test.library.stats.TestDistributions.testQuantileFunctions#Output.MayIgnoreWarningContext#
+#qbeta(log(c(0, 42e-80, 0.1, 0.5, 0.7, 1-42e-80, 1)), 7, 113e11, 1, lower.tail=T, log.p=T)
+[1] 0.000000e+00 2.042740e-24 3.697562e-13 6.326635e-13 7.690718e-13
+[6] 1.000000e+00 1.000000e+00
+
+##com.oracle.truffle.r.test.library.stats.TestDistributions.testQuantileFunctions#Output.MayIgnoreWarningContext#
+#qbeta(log(c(0, 42e-80, 0.1, 0.5, 0.7, 1-42e-80, 1)), 7, 13, 3, lower.tail=F, log.p=T)
+[1] 1.0000000 1.0000000 0.5361327 0.3904742 0.3326837 0.0000000 0.0000000
+
+##com.oracle.truffle.r.test.library.stats.TestDistributions.testQuantileFunctions#Output.MayIgnoreWarningContext#
+#qbeta(log(c(0, 42e-80, 0.1, 0.5, 0.7, 1-42e-80, 1)), 7, 13, 3, lower.tail=T, log.p=T)
+[1] 0.000000e+00 1.677349e-12 2.547294e-01 3.904742e-01 4.499427e-01
+[6] 1.000000e+00 1.000000e+00
+
+##com.oracle.truffle.r.test.library.stats.TestDistributions.testQuantileFunctions#Output.MayIgnoreWarningContext#
+#qbeta(log(c(0, 42e-80, 0.1, 0.5, 0.7, 1-42e-80, 1)), Inf, 0, lower.tail=F, log.p=T)
+[1] 1 1 1 1 1 0 0
+
+##com.oracle.truffle.r.test.library.stats.TestDistributions.testQuantileFunctions#Output.MayIgnoreWarningContext#
+#qbeta(log(c(0, 42e-80, 0.1, 0.5, 0.7, 1-42e-80, 1)), Inf, 0, lower.tail=T, log.p=T)
+[1] 0 1 1 1 1 1 1
+
+##com.oracle.truffle.r.test.library.stats.TestDistributions.testQuantileFunctions#Output.MayIgnoreWarningContext#
+#qcauchy(-0.42e-38, 0, -1)
+[1] NaN
+Warning message:
+In qcauchy(-4.2e-39, 0, -1) : NaNs produced
+
+##com.oracle.truffle.r.test.library.stats.TestDistributions.testQuantileFunctions#Output.MayIgnoreWarningContext#
+#qcauchy(-42, 0, -1)
+[1] NaN
+Warning message:
+In qcauchy(-42, 0, -1) : NaNs produced
+
+##com.oracle.truffle.r.test.library.stats.TestDistributions.testQuantileFunctions#Output.MayIgnoreWarningContext#
+#qcauchy(-Inf, 0, -1)
+[1] NaN
+Warning message:
+In qcauchy(-Inf, 0, -1) : NaNs produced
+
+##com.oracle.truffle.r.test.library.stats.TestDistributions.testQuantileFunctions#Output.MayIgnoreWarningContext#
+#qcauchy(0, -Inf,  -1)
+[1] NaN
+Warning message:
+In qcauchy(0, -Inf, -1) : NaNs produced
+
+##com.oracle.truffle.r.test.library.stats.TestDistributions.testQuantileFunctions#Output.MayIgnoreWarningContext#
+#qcauchy(0, 0, -Inf)
+[1] NaN
+Warning message:
+In qcauchy(0, 0, -Inf) : NaNs produced
+
+##com.oracle.truffle.r.test.library.stats.TestDistributions.testQuantileFunctions#Output.MayIgnoreWarningContext#
+#qcauchy(0, 0, Inf)
+[1] NaN
+Warning message:
+In qcauchy(0, 0, Inf) : NaNs produced
+
+##com.oracle.truffle.r.test.library.stats.TestDistributions.testQuantileFunctions#Output.MayIgnoreWarningContext#
+#qcauchy(0, 0, NaN)
+[1] NaN
+
+##com.oracle.truffle.r.test.library.stats.TestDistributions.testQuantileFunctions#Output.MayIgnoreWarningContext#
+#qcauchy(0, Inf,  -1)
+[1] NaN
+Warning message:
+In qcauchy(0, Inf, -1) : NaNs produced
+
+##com.oracle.truffle.r.test.library.stats.TestDistributions.testQuantileFunctions#Output.MayIgnoreWarningContext#
+#qcauchy(0, NaN,  -1)
+[1] NaN
+
+##com.oracle.truffle.r.test.library.stats.TestDistributions.testQuantileFunctions#Output.MayIgnoreWarningContext#
+#qcauchy(Inf, 0, -1)
+[1] NaN
+Warning message:
+In qcauchy(Inf, 0, -1) : NaNs produced
+
+##com.oracle.truffle.r.test.library.stats.TestDistributions.testQuantileFunctions#Output.MayIgnoreWarningContext#
+#qcauchy(NaN, 0, -1)
+[1] NaN
+
+##com.oracle.truffle.r.test.library.stats.TestDistributions.testQuantileFunctions#Output.MayIgnoreWarningContext#
+#qcauchy(c(0, 42e-80, 0.1, 0.5, 0.7, 1-42e-80, 1), -0.01, 0.03, lower.tail=F, log.p=F)
+[1]           Inf  2.273642e+76  8.233051e-02 -1.000000e-02 -3.179628e-02
+[6]          -Inf          -Inf
+
+##com.oracle.truffle.r.test.library.stats.TestDistributions.testQuantileFunctions#Output.MayIgnoreWarningContext#
+#qcauchy(c(0, 42e-80, 0.1, 0.5, 0.7, 1-42e-80, 1), -0.01, 0.03, lower.tail=T, log.p=F)
+[1]          -Inf -2.273642e+76 -1.023305e-01 -1.000000e-02  1.179628e-02
+[6]           Inf           Inf
+
+##com.oracle.truffle.r.test.library.stats.TestDistributions.testQuantileFunctions#Output.MayIgnoreWarningContext#
+#qcauchy(c(0, 42e-80, 0.1, 0.5, 0.7, 1-42e-80, 1), -5, 5, lower.tail=F, log.p=F)
+[1]           Inf  3.789403e+78  1.038842e+01 -5.000000e+00 -8.632713e+00
+[6]          -Inf          -Inf
+
+##com.oracle.truffle.r.test.library.stats.TestDistributions.testQuantileFunctions#Output.MayIgnoreWarningContext#
+#qcauchy(c(0, 42e-80, 0.1, 0.5, 0.7, 1-42e-80, 1), -5, 5, lower.tail=T, log.p=F)
+[1]          -Inf -3.789403e+78 -2.038842e+01 -5.000000e+00 -1.367287e+00
+[6]           Inf           Inf
+
+##com.oracle.truffle.r.test.library.stats.TestDistributions.testQuantileFunctions#Output.MayIgnoreWarningContext#
+#qcauchy(c(0, 42e-80, 0.1, 0.5, 0.7, 1-42e-80, 1), 0, -1, lower.tail=F, log.p=F)
+[1] NaN NaN NaN NaN NaN NaN NaN
+Warning message:
+In qcauchy(c(0, 4.2e-79, 0.1, 0.5, 0.7, 1 - 4.2e-79, 1), 0, -1,  :
+  NaNs produced
+
+##com.oracle.truffle.r.test.library.stats.TestDistributions.testQuantileFunctions#Output.MayIgnoreWarningContext#
+#qcauchy(c(0, 42e-80, 0.1, 0.5, 0.7, 1-42e-80, 1), 0, -1, lower.tail=T, log.p=F)
+[1] NaN NaN NaN NaN NaN NaN NaN
+Warning message:
+In qcauchy(c(0, 4.2e-79, 0.1, 0.5, 0.7, 1 - 4.2e-79, 1), 0, -1,  :
+  NaNs produced
+
+##com.oracle.truffle.r.test.library.stats.TestDistributions.testQuantileFunctions#Output.MayIgnoreWarningContext#
+#qcauchy(log(c(0, 42e-80, 0.1, 0.5, 0.7, 1-42e-80, 1)), -0.01, 0.03, lower.tail=F, log.p=T)
+[1]           Inf  2.273642e+76  8.233051e-02 -1.000000e-02 -3.179628e-02
+[6]          -Inf          -Inf
+
+##com.oracle.truffle.r.test.library.stats.TestDistributions.testQuantileFunctions#Output.MayIgnoreWarningContext#
+#qcauchy(log(c(0, 42e-80, 0.1, 0.5, 0.7, 1-42e-80, 1)), -0.01, 0.03, lower.tail=T, log.p=T)
+[1]          -Inf -2.273642e+76 -1.023305e-01 -1.000000e-02  1.179628e-02
+[6]           Inf           Inf
+
+##com.oracle.truffle.r.test.library.stats.TestDistributions.testQuantileFunctions#Output.MayIgnoreWarningContext#
+#qcauchy(log(c(0, 42e-80, 0.1, 0.5, 0.7, 1-42e-80, 1)), -5, 5, lower.tail=F, log.p=T)
+[1]           Inf  3.789403e+78  1.038842e+01 -5.000000e+00 -8.632713e+00
+[6]          -Inf          -Inf
+
+##com.oracle.truffle.r.test.library.stats.TestDistributions.testQuantileFunctions#Output.MayIgnoreWarningContext#
+#qcauchy(log(c(0, 42e-80, 0.1, 0.5, 0.7, 1-42e-80, 1)), -5, 5, lower.tail=T, log.p=T)
+[1]          -Inf -3.789403e+78 -2.038842e+01 -5.000000e+00 -1.367287e+00
+[6]           Inf           Inf
+
+##com.oracle.truffle.r.test.library.stats.TestDistributions.testQuantileFunctions#Output.MayIgnoreWarningContext#
+#qcauchy(log(c(0, 42e-80, 0.1, 0.5, 0.7, 1-42e-80, 1)), 0, -1, lower.tail=F, log.p=T)
+[1] NaN NaN NaN NaN NaN NaN NaN
+Warning message:
+In qcauchy(log(c(0, 4.2e-79, 0.1, 0.5, 0.7, 1 - 4.2e-79, 1)), 0,  :
+  NaNs produced
+
+##com.oracle.truffle.r.test.library.stats.TestDistributions.testQuantileFunctions#Output.MayIgnoreWarningContext#
+#qcauchy(log(c(0, 42e-80, 0.1, 0.5, 0.7, 1-42e-80, 1)), 0, -1, lower.tail=T, log.p=T)
+[1] NaN NaN NaN NaN NaN NaN NaN
+Warning message:
+In qcauchy(log(c(0, 4.2e-79, 0.1, 0.5, 0.7, 1 - 4.2e-79, 1)), 0,  :
+  NaNs produced
+
+##com.oracle.truffle.r.test.library.stats.TestDistributions.testQuantileFunctions#Output.MayIgnoreWarningContext#
+#qchisq(-0.42e-38, 1, 1)
+[1] NaN
+Warning message:
+In qchisq(-4.2e-39, 1, 1) : NaNs produced
+
+##com.oracle.truffle.r.test.library.stats.TestDistributions.testQuantileFunctions#Output.MayIgnoreWarningContext#
+#qchisq(-42, 1, 1)
+[1] NaN
+Warning message:
+In qchisq(-42, 1, 1) : NaNs produced
+
+##com.oracle.truffle.r.test.library.stats.TestDistributions.testQuantileFunctions#Output.MayIgnoreWarningContext#
+#qchisq(-Inf, 1, 1)
+[1] NaN
+Warning message:
+In qchisq(-Inf, 1, 1) : NaNs produced
+
+##com.oracle.truffle.r.test.library.stats.TestDistributions.testQuantileFunctions#Output.MayIgnoreWarningContext#
+#qchisq(0, -3,  1)
+[1] NaN
+Warning message:
+In qchisq(0, -3, 1) : NaNs produced
+
+##com.oracle.truffle.r.test.library.stats.TestDistributions.testQuantileFunctions#Output.MayIgnoreWarningContext#
+#qchisq(0, -Inf,  1)
+[1] NaN
+Warning message:
+In qchisq(0, -Inf, 1) : NaNs produced
+
+##com.oracle.truffle.r.test.library.stats.TestDistributions.testQuantileFunctions#Output.MayIgnoreWarningContext#
+#qchisq(0, 0,  1)
+[1] 0
+
+##com.oracle.truffle.r.test.library.stats.TestDistributions.testQuantileFunctions#Output.MayIgnoreWarningContext#
+#qchisq(0, 1, -3)
+[1] NaN
+Warning message:
+In qchisq(0, 1, -3) : NaNs produced
+
+##com.oracle.truffle.r.test.library.stats.TestDistributions.testQuantileFunctions#Output.MayIgnoreWarningContext#
+#qchisq(0, 1, -Inf)
+[1] NaN
+Warning message:
+In qchisq(0, 1, -Inf) : NaNs produced
+
+##com.oracle.truffle.r.test.library.stats.TestDistributions.testQuantileFunctions#Output.MayIgnoreWarningContext#
+#qchisq(0, 1, 0)
+[1] 0
+
+##com.oracle.truffle.r.test.library.stats.TestDistributions.testQuantileFunctions#Output.MayIgnoreWarningContext#
+#qchisq(0, 1, Inf)
+[1] 0
+
+##com.oracle.truffle.r.test.library.stats.TestDistributions.testQuantileFunctions#Output.MayIgnoreWarningContext#
+#qchisq(0, 1, NaN)
+[1] NaN
+
+##com.oracle.truffle.r.test.library.stats.TestDistributions.testQuantileFunctions#Output.MayIgnoreWarningContext#
+#qchisq(0, Inf,  1)
+[1] NaN
+Warning message:
+In qchisq(0, Inf, 1) : NaNs produced
+
+##com.oracle.truffle.r.test.library.stats.TestDistributions.testQuantileFunctions#Output.MayIgnoreWarningContext#
+#qchisq(0, NaN,  1)
+[1] NaN
+
+##com.oracle.truffle.r.test.library.stats.TestDistributions.testQuantileFunctions#Output.MayIgnoreWarningContext#
+#qchisq(Inf, 1, 1)
+[1] NaN
+Warning message:
+In qchisq(Inf, 1, 1) : NaNs produced
+
+##com.oracle.truffle.r.test.library.stats.TestDistributions.testQuantileFunctions#Output.MayIgnoreWarningContext#
+#qchisq(NaN, 1, 1)
+[1] NaN
+
+##com.oracle.truffle.r.test.library.stats.TestDistributions.testQuantileFunctions#Output.MayIgnoreWarningContext#
+#qchisq(c(0, 42e-80, 0.1, 0.5, 0.7, 1-42e-80, 1), 0.13e-8, 1, lower.tail=F, log.p=F)
+[1]           Inf  3.884902e+02  3.497948e+00 1.948256e-308 2.185051e-308
+[6]  0.000000e+00  0.000000e+00
+
+##com.oracle.truffle.r.test.library.stats.TestDistributions.testQuantileFunctions#Output.MayIgnoreWarningContext#
+#qchisq(c(0, 42e-80, 0.1, 0.5, 0.7, 1-42e-80, 1), 0.13e-8, 1, lower.tail=T, log.p=F)
+[1]  0.000000e+00 1.483383e-308 1.540690e-308 1.948256e-308  7.012971e-01
+[6]           Inf           Inf
+
+##com.oracle.truffle.r.test.library.stats.TestDistributions.testQuantileFunctions#Output.MayIgnoreWarningContext#
+#qchisq(c(0, 42e-80, 0.1, 0.5, 0.7, 1-42e-80, 1), 1, 0.13e-8, lower.tail=F, log.p=F)
+[1]         Inf 354.6100738   2.7055435   0.4549364   0.1484719   0.0000000
+[7]   0.0000000
+
+##com.oracle.truffle.r.test.library.stats.TestDistributions.testQuantileFunctions#Output.MayIgnoreWarningContext#
+#qchisq(c(0, 42e-80, 0.1, 0.5, 0.7, 1-42e-80, 1), 1, 0.13e-8, lower.tail=T, log.p=F)
+[1]  0.000000e+00 2.770885e-157  1.579077e-02  4.549364e-01  1.074194e+00
+[6]           Inf           Inf
+
+##com.oracle.truffle.r.test.library.stats.TestDistributions.testQuantileFunctions#Output.MayIgnoreWarningContext#
+#qchisq(c(0, 42e-80, 0.1, 0.5, 0.7, 1-42e-80, 1), 1, 1, lower.tail=F, log.p=F)
+[1]         Inf 391.6893093   5.2187941   1.1036433   0.3860691   0.0000000
+[7]   0.0000000
+
+##com.oracle.truffle.r.test.library.stats.TestDistributions.testQuantileFunctions#Output.MayIgnoreWarningContext#
+#qchisq(c(0, 42e-80, 0.1, 0.5, 0.7, 1-42e-80, 1), 1, 1, lower.tail=T, log.p=F)
+[1]  0.000000e+00 7.532046e-157  4.270125e-02  1.103643e+00  2.372806e+00
+[6]           Inf           Inf
+
+##com.oracle.truffle.r.test.library.stats.TestDistributions.testQuantileFunctions#Output.MayIgnoreWarningContext#
+#qchisq(c(0, 42e-80, 0.1, 0.5, 0.7, 1-42e-80, 1), 420, 4, lower.tail=F, log.p=F)
+[1]       Inf 1232.0142  461.9006  423.3273  408.1833    0.0000    0.0000
+
+##com.oracle.truffle.r.test.library.stats.TestDistributions.testQuantileFunctions#Output.MayIgnoreWarningContext#
+#qchisq(c(0, 42e-80, 0.1, 0.5, 0.7, 1-42e-80, 1), 420, 4, lower.tail=T, log.p=F)
+[1]   0.00000  81.30876 386.96380 423.32729 438.84130       Inf       Inf
+
+##com.oracle.truffle.r.test.library.stats.TestDistributions.testQuantileFunctions#Output.MayIgnoreWarningContext#
+#qchisq(log(c(0, 42e-80, 0.1, 0.5, 0.7, 1-42e-80, 1)), 0.13e-8, 1, lower.tail=F, log.p=T)
+[1]           Inf  3.884902e+02  3.497948e+00 1.948256e-308 2.185051e-308
+[6]  0.000000e+00  0.000000e+00
+
+##com.oracle.truffle.r.test.library.stats.TestDistributions.testQuantileFunctions#Output.MayIgnoreWarningContext#
+#qchisq(log(c(0, 42e-80, 0.1, 0.5, 0.7, 1-42e-80, 1)), 0.13e-8, 1, lower.tail=T, log.p=T)
+[1]  0.000000e+00 1.483383e-308 1.540690e-308 1.948256e-308  7.012971e-01
+[6]           Inf           Inf
+
+##com.oracle.truffle.r.test.library.stats.TestDistributions.testQuantileFunctions#Output.MayIgnoreWarningContext#
+#qchisq(log(c(0, 42e-80, 0.1, 0.5, 0.7, 1-42e-80, 1)), 1, 0.13e-8, lower.tail=F, log.p=T)
+[1]         Inf 354.6100738   2.7055435   0.4549364   0.1484719   0.0000000
+[7]   0.0000000
+
+##com.oracle.truffle.r.test.library.stats.TestDistributions.testQuantileFunctions#Output.MayIgnoreWarningContext#
+#qchisq(log(c(0, 42e-80, 0.1, 0.5, 0.7, 1-42e-80, 1)), 1, 0.13e-8, lower.tail=T, log.p=T)
+[1]  0.000000e+00 2.770885e-157  1.579077e-02  4.549364e-01  1.074194e+00
+[6]           Inf           Inf
+
+##com.oracle.truffle.r.test.library.stats.TestDistributions.testQuantileFunctions#Output.MayIgnoreWarningContext#
+#qchisq(log(c(0, 42e-80, 0.1, 0.5, 0.7, 1-42e-80, 1)), 1, 1, lower.tail=F, log.p=T)
+[1]         Inf 391.6893093   5.2187941   1.1036433   0.3860691   0.0000000
+[7]   0.0000000
+
+##com.oracle.truffle.r.test.library.stats.TestDistributions.testQuantileFunctions#Output.MayIgnoreWarningContext#
+#qchisq(log(c(0, 42e-80, 0.1, 0.5, 0.7, 1-42e-80, 1)), 1, 1, lower.tail=T, log.p=T)
+[1]  0.000000e+00 7.532046e-157  4.270125e-02  1.103643e+00  2.372806e+00
+[6]           Inf           Inf
+
+##com.oracle.truffle.r.test.library.stats.TestDistributions.testQuantileFunctions#Output.MayIgnoreWarningContext#
+#qchisq(log(c(0, 42e-80, 0.1, 0.5, 0.7, 1-42e-80, 1)), 420, 4, lower.tail=F, log.p=T)
+[1]       Inf 1232.0142  461.9006  423.3273  408.1833    0.0000    0.0000
+
+##com.oracle.truffle.r.test.library.stats.TestDistributions.testQuantileFunctions#Output.MayIgnoreWarningContext#
+#qchisq(log(c(0, 42e-80, 0.1, 0.5, 0.7, 1-42e-80, 1)), 420, 4, lower.tail=T, log.p=T)
+[1]   0.00000  81.30876 386.96380 423.32729 438.84130       Inf       Inf
+
+##com.oracle.truffle.r.test.library.stats.TestDistributions.testQuantileFunctions#Output.MayIgnoreWarningContext#
+#qexp(-0.42e-38, 13e-20)
+[1] NaN
+Warning message:
+In qexp(-4.2e-39, 1.3e-19) : NaNs produced
+
+##com.oracle.truffle.r.test.library.stats.TestDistributions.testQuantileFunctions#Output.MayIgnoreWarningContext#
+#qexp(-42, 13e-20)
+[1] NaN
+Warning message:
+In qexp(-42, 1.3e-19) : NaNs produced
+
+##com.oracle.truffle.r.test.library.stats.TestDistributions.testQuantileFunctions#Output.MayIgnoreWarningContext#
+#qexp(-Inf, 13e-20)
+[1] NaN
+Warning message:
+In qexp(-Inf, 1.3e-19) : NaNs produced
+
+##com.oracle.truffle.r.test.library.stats.TestDistributions.testQuantileFunctions#Output.MayIgnoreWarningContext#
+#qexp(0, -1)
+[1] NaN
+Warning message:
+In qexp(0, -1) : NaNs produced
+
+##com.oracle.truffle.r.test.library.stats.TestDistributions.testQuantileFunctions#Output.MayIgnoreWarningContext#
+#qexp(0, -Inf)
+[1] 0
+
+##com.oracle.truffle.r.test.library.stats.TestDistributions.testQuantileFunctions#Output.MayIgnoreWarningContext#
+#qexp(0, 0)
+[1] 0
+
+##com.oracle.truffle.r.test.library.stats.TestDistributions.testQuantileFunctions#Output.MayIgnoreWarningContext#
+#qexp(0, Inf)
+[1] 0
+
+##com.oracle.truffle.r.test.library.stats.TestDistributions.testQuantileFunctions#Output.MayIgnoreWarningContext#
+#qexp(0, NaN)
+[1] NaN
+
+##com.oracle.truffle.r.test.library.stats.TestDistributions.testQuantileFunctions#Output.MayIgnoreWarningContext#
+#qexp(Inf, 13e-20)
+[1] NaN
+Warning message:
+In qexp(Inf, 1.3e-19) : NaNs produced
+
+##com.oracle.truffle.r.test.library.stats.TestDistributions.testQuantileFunctions#Output.MayIgnoreWarningContext#
+#qexp(NaN, 13e-20)
+[1] NaN
+
+##com.oracle.truffle.r.test.library.stats.TestDistributions.testQuantileFunctions#Output.MayIgnoreWarningContext#
+#qexp(c(0, 42e-80, 0.1, 0.5, 0.7, 1-42e-80, 1), 13e-20, lower.tail=F, log.p=F)
+[1]          Inf 1.388224e+21 1.771219e+19 5.331901e+18 2.743653e+18
+[6] 0.000000e+00 0.000000e+00
+
+##com.oracle.truffle.r.test.library.stats.TestDistributions.testQuantileFunctions#Output.MayIgnoreWarningContext#
+#qexp(c(0, 42e-80, 0.1, 0.5, 0.7, 1-42e-80, 1), 13e-20, lower.tail=T, log.p=F)
+[1] 0.000000e+00 3.230769e-60 8.104655e+17 5.331901e+18 9.261329e+18
+[6]          Inf          Inf
+
+##com.oracle.truffle.r.test.library.stats.TestDistributions.testQuantileFunctions#Output.MayIgnoreWarningContext#
+#qexp(c(0, 42e-80, 0.1, 0.5, 0.7, 1-42e-80, 1), 42, lower.tail=F, log.p=F)
+[1]         Inf 4.296884234 0.054823455 0.016503504 0.008492261 0.000000000
+[7] 0.000000000
+
+##com.oracle.truffle.r.test.library.stats.TestDistributions.testQuantileFunctions#Output.MayIgnoreWarningContext#
+#qexp(c(0, 42e-80, 0.1, 0.5, 0.7, 1-42e-80, 1), 42, lower.tail=T, log.p=F)
+[1] 0.000000e+00 1.000000e-80 2.508584e-03 1.650350e-02 2.866602e-02
+[6]          Inf          Inf
+
+##com.oracle.truffle.r.test.library.stats.TestDistributions.testQuantileFunctions#Output.MayIgnoreWarningContext#
+#qexp(c(0, 42e-80, 0.1, 0.5, 0.7, 1-42e-80, 1), 42e123, lower.tail=F, log.p=F)
+[1]           Inf 4.296884e-123 5.482345e-125 1.650350e-125 8.492261e-126
+[6]  0.000000e+00  0.000000e+00
+
+##com.oracle.truffle.r.test.library.stats.TestDistributions.testQuantileFunctions#Output.MayIgnoreWarningContext#
+#qexp(c(0, 42e-80, 0.1, 0.5, 0.7, 1-42e-80, 1), 42e123, lower.tail=T, log.p=F)
+[1]  0.000000e+00 1.000000e-203 2.508584e-126 1.650350e-125 2.866602e-125
+[6]           Inf           Inf
+
+##com.oracle.truffle.r.test.library.stats.TestDistributions.testQuantileFunctions#Output.MayIgnoreWarningContext#
+#qexp(log(c(0, 42e-80, 0.1, 0.5, 0.7, 1-42e-80, 1)), 13e-20, lower.tail=F, log.p=T)
+[1]          Inf 1.388224e+21 1.771219e+19 5.331901e+18 2.743653e+18
+[6] 0.000000e+00 0.000000e+00
+
+##com.oracle.truffle.r.test.library.stats.TestDistributions.testQuantileFunctions#Output.MayIgnoreWarningContext#
+#qexp(log(c(0, 42e-80, 0.1, 0.5, 0.7, 1-42e-80, 1)), 13e-20, lower.tail=T, log.p=T)
+[1] 0.000000e+00 3.230769e-60 8.104655e+17 5.331901e+18 9.261329e+18
+[6]          Inf          Inf
+
+##com.oracle.truffle.r.test.library.stats.TestDistributions.testQuantileFunctions#Output.MayIgnoreWarningContext#
+#qexp(log(c(0, 42e-80, 0.1, 0.5, 0.7, 1-42e-80, 1)), 42, lower.tail=F, log.p=T)
+[1]         Inf 4.296884234 0.054823455 0.016503504 0.008492261 0.000000000
+[7] 0.000000000
+
+##com.oracle.truffle.r.test.library.stats.TestDistributions.testQuantileFunctions#Output.MayIgnoreWarningContext#
+#qexp(log(c(0, 42e-80, 0.1, 0.5, 0.7, 1-42e-80, 1)), 42, lower.tail=T, log.p=T)
+[1] 0.000000e+00 1.000000e-80 2.508584e-03 1.650350e-02 2.866602e-02
+[6]          Inf          Inf
+
+##com.oracle.truffle.r.test.library.stats.TestDistributions.testQuantileFunctions#Output.MayIgnoreWarningContext#
+#qexp(log(c(0, 42e-80, 0.1, 0.5, 0.7, 1-42e-80, 1)), 42e123, lower.tail=F, log.p=T)
+[1]           Inf 4.296884e-123 5.482345e-125 1.650350e-125 8.492261e-126
+[6]  0.000000e+00  0.000000e+00
+
+##com.oracle.truffle.r.test.library.stats.TestDistributions.testQuantileFunctions#Output.MayIgnoreWarningContext#
+#qexp(log(c(0, 42e-80, 0.1, 0.5, 0.7, 1-42e-80, 1)), 42e123, lower.tail=T, log.p=T)
+[1]  0.000000e+00 1.000000e-203 2.508584e-126 1.650350e-125 2.866602e-125
+[6]           Inf           Inf
+
+##com.oracle.truffle.r.test.library.stats.TestDistributions.testQuantileFunctions#Output.MayIgnoreWarningContext#
+#qf(-0.42e-38, 5, 5, 5)
+[1] NaN
+Warning message:
+In qf(-4.2e-39, 5, 5, 5) : NaNs produced
+
+##com.oracle.truffle.r.test.library.stats.TestDistributions.testQuantileFunctions#Output.MayIgnoreWarningContext#
+#qf(-42, 5, 5, 5)
+[1] NaN
+Warning message:
+In qf(-42, 5, 5, 5) : NaNs produced
+
+##com.oracle.truffle.r.test.library.stats.TestDistributions.testQuantileFunctions#Output.MayIgnoreWarningContext#
+#qf(-Inf, 5, 5, 5)
+[1] NaN
+Warning message:
+In qf(-Inf, 5, 5, 5) : NaNs produced
+
+##com.oracle.truffle.r.test.library.stats.TestDistributions.testQuantileFunctions#Output.MayIgnoreWarningContext#
+#qf(0, -1,  5,  5)
+[1] NaN
+Warning message:
+In qf(0, -1, 5, 5) : NaNs produced
+
+##com.oracle.truffle.r.test.library.stats.TestDistributions.testQuantileFunctions#Output.MayIgnoreWarningContext#
+#qf(0, -Inf,  5,  5)
+[1] NaN
+Warning message:
+In qf(0, -Inf, 5, 5) : NaNs produced
+
+##com.oracle.truffle.r.test.library.stats.TestDistributions.testQuantileFunctions#Output.MayIgnoreWarningContext#
+#qf(0, 0,  5,  5)
+[1] NaN
+Warning message:
+In qf(0, 0, 5, 5) : NaNs produced
+
+##com.oracle.truffle.r.test.library.stats.TestDistributions.testQuantileFunctions#Output.MayIgnoreWarningContext#
+#qf(0, 5,  5, -1)
+[1] NaN
+Warning message:
+In qf(0, 5, 5, -1) : NaNs produced
+
+##com.oracle.truffle.r.test.library.stats.TestDistributions.testQuantileFunctions#Output.MayIgnoreWarningContext#
+#qf(0, 5,  5, -Inf)
+[1] NaN
+Warning message:
+In qf(0, 5, 5, -Inf) : NaNs produced
+
+##com.oracle.truffle.r.test.library.stats.TestDistributions.testQuantileFunctions#Output.MayIgnoreWarningContext#
+#qf(0, 5,  5, 0)
+[1] 0
+
+##com.oracle.truffle.r.test.library.stats.TestDistributions.testQuantileFunctions#Output.MayIgnoreWarningContext#
+#qf(0, 5,  5, Inf)
+[1] NaN
+Warning message:
+In qf(0, 5, 5, Inf) : NaNs produced
+
+##com.oracle.truffle.r.test.library.stats.TestDistributions.testQuantileFunctions#Output.MayIgnoreWarningContext#
+#qf(0, 5,  5, NaN)
+[1] NaN
+
+##com.oracle.truffle.r.test.library.stats.TestDistributions.testQuantileFunctions#Output.MayIgnoreWarningContext#
+#qf(0, 5, -1,  5)
+[1] NaN
+Warning message:
+In qf(0, 5, -1, 5) : NaNs produced
+
+##com.oracle.truffle.r.test.library.stats.TestDistributions.testQuantileFunctions#Output.MayIgnoreWarningContext#
+#qf(0, 5, -Inf,  5)
+[1] NaN
+Warning message:
+In qf(0, 5, -Inf, 5) : NaNs produced
+
+##com.oracle.truffle.r.test.library.stats.TestDistributions.testQuantileFunctions#Output.MayIgnoreWarningContext#
+#qf(0, 5, 0,  5)
+[1] NaN
+Warning message:
+In qf(0, 5, 0, 5) : NaNs produced
+
+##com.oracle.truffle.r.test.library.stats.TestDistributions.testQuantileFunctions#Output.MayIgnoreWarningContext#
+#qf(0, 5, Inf,  5)
+[1] 0
+
+##com.oracle.truffle.r.test.library.stats.TestDistributions.testQuantileFunctions#Output.MayIgnoreWarningContext#
+#qf(0, 5, NaN,  5)
+[1] NaN
+
+##com.oracle.truffle.r.test.library.stats.TestDistributions.testQuantileFunctions#Output.MayIgnoreWarningContext#
+#qf(0, Inf,  5,  5)
+[1] 0
+
+##com.oracle.truffle.r.test.library.stats.TestDistributions.testQuantileFunctions#Output.MayIgnoreWarningContext#
+#qf(0, NaN,  5,  5)
+[1] NaN
+
+##com.oracle.truffle.r.test.library.stats.TestDistributions.testQuantileFunctions#Output.MayIgnoreWarningContext#
+#qf(Inf, 5, 5, 5)
+[1] NaN
+Warning message:
+In qf(Inf, 5, 5, 5) : NaNs produced
+
+##com.oracle.truffle.r.test.library.stats.TestDistributions.testQuantileFunctions#Output.MayIgnoreWarningContext#
+#qf(NaN, 5, 5, 5)
+[1] NaN
+
+##com.oracle.truffle.r.test.library.stats.TestDistributions.testQuantileFunctions#Output.MayIgnoreWarningContext#
+#qf(c(0, 42e-80, 0.1, 0.5, 0.7, 1-42e-80, 1), 0.12e-10, 6, 31e10, lower.tail=F, log.p=F)
+[1]          Inf          Inf 7.505999e+26 7.505999e+26 7.505999e+26
+[6] 0.000000e+00 0.000000e+00
+There were 50 or more warnings (use warnings() to see the first 50)
+
+##com.oracle.truffle.r.test.library.stats.TestDistributions.testQuantileFunctions#Output.MayIgnoreWarningContext#
+#qf(c(0, 42e-80, 0.1, 0.5, 0.7, 1-42e-80, 1), 0.12e-10, 6, 31e10, lower.tail=T, log.p=F)
+[1] 0.000000e+00 5.090863e+20 7.505999e+26 7.505999e+26 7.505999e+26
+[6]          Inf          Inf
+There were 50 or more warnings (use warnings() to see the first 50)
+
+##com.oracle.truffle.r.test.library.stats.TestDistributions.testQuantileFunctions#Output.MayIgnoreWarningContext#
+#qf(c(0, 42e-80, 0.1, 0.5, 0.7, 1-42e-80, 1), 5, 0.12e-10, 5, lower.tail=F, log.p=F)
+[1]     Inf     Inf 3602.88 3602.88 3602.88    0.00    0.00
+
+##com.oracle.truffle.r.test.library.stats.TestDistributions.testQuantileFunctions#Output.MayIgnoreWarningContext#
+#qf(c(0, 42e-80, 0.1, 0.5, 0.7, 1-42e-80, 1), 5, 0.12e-10, 5, lower.tail=T, log.p=F)
+[1] 0.000000e+00 1.293365e-38 3.602880e+03 3.602880e+03 3.602880e+03
+[6]          Inf          Inf
+
+##com.oracle.truffle.r.test.library.stats.TestDistributions.testQuantileFunctions#Output.MayIgnoreWarningContext#
+#qf(c(0, 42e-80, 0.1, 0.5, 0.7, 1-42e-80, 1), 5, 5, 5, lower.tail=F, log.p=F)
+[1]      Inf      Inf 6.772533 2.075393 1.308959 0.000000 0.000000
+
+##com.oracle.truffle.r.test.library.stats.TestDistributions.testQuantileFunctions#Output.MayIgnoreWarningContext#
+#qf(c(0, 42e-80, 0.1, 0.5, 0.7, 1-42e-80, 1), 5, 5, 5, lower.tail=T, log.p=F)
+[1] 0.000000e+00 6.160198e-32 6.602106e-01 2.075393e+00 3.312503e+00
+[6]          Inf          Inf
+
+##com.oracle.truffle.r.test.library.stats.TestDistributions.testQuantileFunctions#Output.MayIgnoreWarningContext#
+#qf(c(0, 42e-80, 0.1, 0.5, 0.7, 1-42e-80, 1), 5, 6, 0.12e-10, lower.tail=F, log.p=F)
+[1]       Inf       Inf 3.1075117 0.9765364 0.6067423 0.0000000 0.0000000
+
+##com.oracle.truffle.r.test.library.stats.TestDistributions.testQuantileFunctions#Output.MayIgnoreWarningContext#
+#qf(c(0, 42e-80, 0.1, 0.5, 0.7, 1-42e-80, 1), 5, 6, 0.12e-10, lower.tail=T, log.p=F)
+[1] 0.000000e+00 2.344125e-32 2.937283e-01 9.765364e-01 1.560462e+00
+[6]          Inf          Inf
+
+##com.oracle.truffle.r.test.library.stats.TestDistributions.testQuantileFunctions#Output.MayIgnoreWarningContext#
+#qf(log(c(0, 42e-80, 0.1, 0.5, 0.7, 1-42e-80, 1)), 0.12e-10, 6, 31e10, lower.tail=F, log.p=T)
+[1]          Inf          Inf 7.505999e+26 7.505999e+26 7.505999e+26
+[6] 0.000000e+00 0.000000e+00
+There were 50 or more warnings (use warnings() to see the first 50)
+
+##com.oracle.truffle.r.test.library.stats.TestDistributions.testQuantileFunctions#Output.MayIgnoreWarningContext#
+#qf(log(c(0, 42e-80, 0.1, 0.5, 0.7, 1-42e-80, 1)), 0.12e-10, 6, 31e10, lower.tail=T, log.p=T)
+[1] 0.000000e+00 5.090863e+20 7.505999e+26 7.505999e+26 7.505999e+26
+[6]          Inf          Inf
+There were 50 or more warnings (use warnings() to see the first 50)
+
+##com.oracle.truffle.r.test.library.stats.TestDistributions.testQuantileFunctions#Output.MayIgnoreWarningContext#
+#qf(log(c(0, 42e-80, 0.1, 0.5, 0.7, 1-42e-80, 1)), 5, 0.12e-10, 5, lower.tail=F, log.p=T)
+[1]     Inf     Inf 3602.88 3602.88 3602.88    0.00    0.00
+
+##com.oracle.truffle.r.test.library.stats.TestDistributions.testQuantileFunctions#Output.MayIgnoreWarningContext#
+#qf(log(c(0, 42e-80, 0.1, 0.5, 0.7, 1-42e-80, 1)), 5, 0.12e-10, 5, lower.tail=T, log.p=T)
+[1] 0.000000e+00 1.293365e-38 3.602880e+03 3.602880e+03 3.602880e+03
+[6]          Inf          Inf
+
+##com.oracle.truffle.r.test.library.stats.TestDistributions.testQuantileFunctions#Output.MayIgnoreWarningContext#
+#qf(log(c(0, 42e-80, 0.1, 0.5, 0.7, 1-42e-80, 1)), 5, 5, 5, lower.tail=F, log.p=T)
+[1]      Inf      Inf 6.772533 2.075393 1.308959 0.000000 0.000000
+
+##com.oracle.truffle.r.test.library.stats.TestDistributions.testQuantileFunctions#Output.MayIgnoreWarningContext#
+#qf(log(c(0, 42e-80, 0.1, 0.5, 0.7, 1-42e-80, 1)), 5, 5, 5, lower.tail=T, log.p=T)
+[1] 0.000000e+00 6.160198e-32 6.602106e-01 2.075393e+00 3.312503e+00
+[6]          Inf          Inf
+
+##com.oracle.truffle.r.test.library.stats.TestDistributions.testQuantileFunctions#Output.MayIgnoreWarningContext#
+#qf(log(c(0, 42e-80, 0.1, 0.5, 0.7, 1-42e-80, 1)), 5, 6, 0.12e-10, lower.tail=F, log.p=T)
+[1]       Inf       Inf 3.1075117 0.9765364 0.6067423 0.0000000 0.0000000
+
+##com.oracle.truffle.r.test.library.stats.TestDistributions.testQuantileFunctions#Output.MayIgnoreWarningContext#
+#qf(log(c(0, 42e-80, 0.1, 0.5, 0.7, 1-42e-80, 1)), 5, 6, 0.12e-10, lower.tail=T, log.p=T)
+[1] 0.000000e+00 2.344125e-32 2.937283e-01 9.765364e-01 1.560462e+00
+[6]          Inf          Inf
+
+##com.oracle.truffle.r.test.library.stats.TestDistributions.testQuantileFunctions#Output.MayIgnoreWarningContext#
+#qgamma(-0.42e-38, 1, scale=2)
+[1] NaN
+Warning message:
+In qgamma(-4.2e-39, 1, scale = 2) : NaNs produced
+
+##com.oracle.truffle.r.test.library.stats.TestDistributions.testQuantileFunctions#Output.MayIgnoreWarningContext#
+#qgamma(-42, 1, scale=2)
+[1] NaN
+Warning message:
+In qgamma(-42, 1, scale = 2) : NaNs produced
+
+##com.oracle.truffle.r.test.library.stats.TestDistributions.testQuantileFunctions#Output.MayIgnoreWarningContext#
+#qgamma(-Inf, 1, scale=2)
+[1] NaN
+Warning message:
+In qgamma(-Inf, 1, scale = 2) : NaNs produced
+
+##com.oracle.truffle.r.test.library.stats.TestDistributions.testQuantileFunctions#Output.MayIgnoreWarningContext#
+#qgamma(0, -1,  scale=2)
+[1] 0
+
+##com.oracle.truffle.r.test.library.stats.TestDistributions.testQuantileFunctions#Output.MayIgnoreWarningContext#
+#qgamma(0, -Inf,  scale=2)
+[1] 0
+
+##com.oracle.truffle.r.test.library.stats.TestDistributions.testQuantileFunctions#Output.MayIgnoreWarningContext#
+#qgamma(0, 0,  scale=2)
+[1] 0
+
+##com.oracle.truffle.r.test.library.stats.TestDistributions.testQuantileFunctions#Output.MayIgnoreWarningContext#
+#qgamma(0, 1, -1)
+[1] 0
+
+##com.oracle.truffle.r.test.library.stats.TestDistributions.testQuantileFunctions#Output.MayIgnoreWarningContext#
+#qgamma(0, 1, -Inf)
+[1] 0
+
+##com.oracle.truffle.r.test.library.stats.TestDistributions.testQuantileFunctions#Output.MayIgnoreWarningContext#
+#qgamma(0, 1, 0)
+[1] 0
+
+##com.oracle.truffle.r.test.library.stats.TestDistributions.testQuantileFunctions#Output.MayIgnoreWarningContext#
+#qgamma(0, 1, Inf)
+[1] 0
+
+##com.oracle.truffle.r.test.library.stats.TestDistributions.testQuantileFunctions#Output.MayIgnoreWarningContext#
+#qgamma(0, 1, NaN)
+[1] NaN
+
+##com.oracle.truffle.r.test.library.stats.TestDistributions.testQuantileFunctions#Output.MayIgnoreWarningContext#
+#qgamma(0, Inf,  scale=2)
+[1] 0
+
+##com.oracle.truffle.r.test.library.stats.TestDistributions.testQuantileFunctions#Output.MayIgnoreWarningContext#
+#qgamma(0, NaN,  scale=2)
+[1] NaN
+
+##com.oracle.truffle.r.test.library.stats.TestDistributions.testQuantileFunctions#Output.MayIgnoreWarningContext#
+#qgamma(Inf, 1, scale=2)
+[1] NaN
+Warning message:
+In qgamma(Inf, 1, scale = 2) : NaNs produced
+
+##com.oracle.truffle.r.test.library.stats.TestDistributions.testQuantileFunctions#Output.MayIgnoreWarningContext#
+#qgamma(NaN, 1, scale=2)
+[1] NaN
+
+##com.oracle.truffle.r.test.library.stats.TestDistributions.testQuantileFunctions#Output.MayIgnoreWarningContext#
+#qgamma(c(0, 42e-80, 0.1, 0.5, 0.7, 1-42e-80, 1), 1, scale=2, lower.tail=F, log.p=F)
+[1]         Inf 360.9382756   4.6051702   1.3862944   0.7133499   0.0000000
+[7]   0.0000000
+
+##com.oracle.truffle.r.test.library.stats.TestDistributions.testQuantileFunctions#Output.MayIgnoreWarningContext#
+#qgamma(c(0, 42e-80, 0.1, 0.5, 0.7, 1-42e-80, 1), 1, scale=2, lower.tail=T, log.p=F)
+[1] 0.000000e+00 8.400000e-79 2.107210e-01 1.386294e+00 2.407946e+00
+[6]          Inf          Inf
+
+##com.oracle.truffle.r.test.library.stats.TestDistributions.testQuantileFunctions#Output.MayIgnoreWarningContext#
+#qgamma(c(0, 42e-80, 0.1, 0.5, 0.7, 1-42e-80, 1), 11e11, scale=23e-11, lower.tail=F, log.p=F)
+[1]      Inf 253.0045 253.0003 253.0000 252.9999   0.0000   0.0000
+
+##com.oracle.truffle.r.test.library.stats.TestDistributions.testQuantileFunctions#Output.MayIgnoreWarningContext#
+#qgamma(c(0, 42e-80, 0.1, 0.5, 0.7, 1-42e-80, 1), 11e11, scale=23e-11, lower.tail=T, log.p=F)
+[1]   0.0000 252.9955 252.9997 253.0000 253.0001      Inf      Inf
+
+##com.oracle.truffle.r.test.library.stats.TestDistributions.testQuantileFunctions#Output.MayIgnoreWarningContext#
+#qgamma(log(c(0, 42e-80, 0.1, 0.5, 0.7, 1-42e-80, 1)), 1, scale=2, lower.tail=F, log.p=T)
+[1]         Inf 360.9382756   4.6051702   1.3862944   0.7133499   0.0000000
+[7]   0.0000000
+
+##com.oracle.truffle.r.test.library.stats.TestDistributions.testQuantileFunctions#Output.MayIgnoreWarningContext#
+#qgamma(log(c(0, 42e-80, 0.1, 0.5, 0.7, 1-42e-80, 1)), 1, scale=2, lower.tail=T, log.p=T)
+[1] 0.000000e+00 8.400000e-79 2.107210e-01 1.386294e+00 2.407946e+00
+[6]          Inf          Inf
+
+##com.oracle.truffle.r.test.library.stats.TestDistributions.testQuantileFunctions#Output.MayIgnoreWarningContext#
+#qgamma(log(c(0, 42e-80, 0.1, 0.5, 0.7, 1-42e-80, 1)), 11e11, scale=23e-11, lower.tail=F, log.p=T)
+[1]      Inf 253.0045 253.0003 253.0000 252.9999   0.0000   0.0000
+
+##com.oracle.truffle.r.test.library.stats.TestDistributions.testQuantileFunctions#Output.MayIgnoreWarningContext#
+#qgamma(log(c(0, 42e-80, 0.1, 0.5, 0.7, 1-42e-80, 1)), 11e11, scale=23e-11, lower.tail=T, log.p=T)
+[1]   0.0000 252.9955 252.9997 253.0000 253.0001      Inf      Inf
+
+##com.oracle.truffle.r.test.library.stats.TestDistributions.testQuantileFunctions#Output.MayIgnoreWarningContext#
+#qhyper(-0.42e-38, 7, 11, 4)
+[1] NaN
+Warning message:
+In qhyper(-4.2e-39, 7, 11, 4) : NaNs produced
+
+##com.oracle.truffle.r.test.library.stats.TestDistributions.testQuantileFunctions#Output.MayIgnoreWarningContext#
+#qhyper(-42, 7, 11, 4)
+[1] NaN
+Warning message:
+In qhyper(-42, 7, 11, 4) : NaNs produced
+
+##com.oracle.truffle.r.test.library.stats.TestDistributions.testQuantileFunctions#Output.MayIgnoreWarningContext#
+#qhyper(-Inf, 7, 11, 4)
+[1] NaN
+Warning message:
+In qhyper(-Inf, 7, 11, 4) : NaNs produced
+
+##com.oracle.truffle.r.test.library.stats.TestDistributions.testQuantileFunctions#Output.MayIgnoreWarningContext#
+#qhyper(0, -10,  11,  4)
+[1] NaN
+Warning message:
+In qhyper(0, -10, 11, 4) : NaNs produced
+
+##com.oracle.truffle.r.test.library.stats.TestDistributions.testQuantileFunctions#Output.MayIgnoreWarningContext#
+#qhyper(0, -Inf,  11,  4)
+[1] NaN
+Warning message:
+In qhyper(0, -Inf, 11, 4) : NaNs produced
+
+##com.oracle.truffle.r.test.library.stats.TestDistributions.testQuantileFunctions#Output.MayIgnoreWarningContext#
+#qhyper(0, 0.3,  11,  4)
+[1] 0
+
+##com.oracle.truffle.r.test.library.stats.TestDistributions.testQuantileFunctions#Output.MayIgnoreWarningContext#
+#qhyper(0, 7,  11, -10)
+[1] NaN
+Warning message:
+In qhyper(0, 7, 11, -10) : NaNs produced
+
+##com.oracle.truffle.r.test.library.stats.TestDistributions.testQuantileFunctions#Output.MayIgnoreWarningContext#
+#qhyper(0, 7,  11, -Inf)
+[1] NaN
+Warning message:
+In qhyper(0, 7, 11, -Inf) : NaNs produced
+
+##com.oracle.truffle.r.test.library.stats.TestDistributions.testQuantileFunctions#Output.MayIgnoreWarningContext#
+#qhyper(0, 7,  11, 0.3)
+[1] 0
+
+##com.oracle.truffle.r.test.library.stats.TestDistributions.testQuantileFunctions#Output.MayIgnoreWarningContext#
+#qhyper(0, 7,  11, Inf)
+[1] NaN
+Warning message:
+In qhyper(0, 7, 11, Inf) : NaNs produced
+
+##com.oracle.truffle.r.test.library.stats.TestDistributions.testQuantileFunctions#Output.MayIgnoreWarningContext#
+#qhyper(0, 7,  11, NaN)
+[1] NaN
+
+##com.oracle.truffle.r.test.library.stats.TestDistributions.testQuantileFunctions#Output.MayIgnoreWarningContext#
+#qhyper(0, 7, -10,  4)
+[1] NaN
+Warning message:
+In qhyper(0, 7, -10, 4) : NaNs produced
+
+##com.oracle.truffle.r.test.library.stats.TestDistributions.testQuantileFunctions#Output.MayIgnoreWarningContext#
+#qhyper(0, 7, -Inf,  4)
+[1] NaN
+Warning message:
+In qhyper(0, 7, -Inf, 4) : NaNs produced
+
+##com.oracle.truffle.r.test.library.stats.TestDistributions.testQuantileFunctions#Output.MayIgnoreWarningContext#
+#qhyper(0, 7, 0.3,  4)
+[1] 4
+
+##com.oracle.truffle.r.test.library.stats.TestDistributions.testQuantileFunctions#Output.MayIgnoreWarningContext#
+#qhyper(0, 7, Inf,  4)
+[1] NaN
+Warning message:
+In qhyper(0, 7, Inf, 4) : NaNs produced
+
+##com.oracle.truffle.r.test.library.stats.TestDistributions.testQuantileFunctions#Output.MayIgnoreWarningContext#
+#qhyper(0, 7, NaN,  4)
+[1] NaN
+
+##com.oracle.truffle.r.test.library.stats.TestDistributions.testQuantileFunctions#Output.MayIgnoreWarningContext#
+#qhyper(0, Inf,  11,  4)
+[1] NaN
+Warning message:
+In qhyper(0, Inf, 11, 4) : NaNs produced
+
+##com.oracle.truffle.r.test.library.stats.TestDistributions.testQuantileFunctions#Output.MayIgnoreWarningContext#
+#qhyper(0, NaN,  11,  4)
+[1] NaN
+
+##com.oracle.truffle.r.test.library.stats.TestDistributions.testQuantileFunctions#Output.MayIgnoreWarningContext#
+#qhyper(Inf, 7, 11, 4)
+[1] NaN
+Warning message:
+In qhyper(Inf, 7, 11, 4) : NaNs produced
+
+##com.oracle.truffle.r.test.library.stats.TestDistributions.testQuantileFunctions#Output.MayIgnoreWarningContext#
+#qhyper(NaN, 7, 11, 4)
+[1] NaN
+
+##com.oracle.truffle.r.test.library.stats.TestDistributions.testQuantileFunctions#Output.MayIgnoreWarningContext#
+#qhyper(c(0, 42e-80, 0.1, 0.5, 0.7, 1-42e-80, 1), 11, 7e12, 7, lower.tail=F, log.p=F)
+[1] 7 1 0 0 0 0 0
+
+##com.oracle.truffle.r.test.library.stats.TestDistributions.testQuantileFunctions#Output.MayIgnoreWarningContext#
+#qhyper(c(0, 42e-80, 0.1, 0.5, 0.7, 1-42e-80, 1), 11, 7e12, 7, lower.tail=T, log.p=F)
+[1] 0 0 0 0 0 7 7
+
+##com.oracle.truffle.r.test.library.stats.TestDistributions.testQuantileFunctions#Output.MayIgnoreWarningContext#
+#qhyper(c(0, 42e-80, 0.1, 0.5, 0.7, 1-42e-80, 1), 3, 4, 10, lower.tail=F, log.p=F)
+[1] NaN NaN NaN NaN NaN NaN NaN
+Warning message:
+In qhyper(c(0, 4.2e-79, 0.1, 0.5, 0.7, 1 - 4.2e-79, 1), 3, 4, 10,  :
+  NaNs produced
+
+##com.oracle.truffle.r.test.library.stats.TestDistributions.testQuantileFunctions#Output.MayIgnoreWarningContext#
+#qhyper(c(0, 42e-80, 0.1, 0.5, 0.7, 1-42e-80, 1), 3, 4, 10, lower.tail=T, log.p=F)
+[1] NaN NaN NaN NaN NaN NaN NaN
+Warning message:
+In qhyper(c(0, 4.2e-79, 0.1, 0.5, 0.7, 1 - 4.2e-79, 1), 3, 4, 10,  :
+  NaNs produced
+
+##com.oracle.truffle.r.test.library.stats.TestDistributions.testQuantileFunctions#Output.MayIgnoreWarningContext#
+#qhyper(c(0, 42e-80, 0.1, 0.5, 0.7, 1-42e-80, 1), 5, 5, 5, lower.tail=F, log.p=F)
+[1] 5 5 4 2 2 0 0
+
+##com.oracle.truffle.r.test.library.stats.TestDistributions.testQuantileFunctions#Output.MayIgnoreWarningContext#
+#qhyper(c(0, 42e-80, 0.1, 0.5, 0.7, 1-42e-80, 1), 5, 5, 5, lower.tail=T, log.p=F)
+[1] 0 0 1 2 3 5 5
+
+##com.oracle.truffle.r.test.library.stats.TestDistributions.testQuantileFunctions#Output.MayIgnoreWarningContext#
+#qhyper(c(0, 42e-80, 0.1, 0.5, 0.7, 1-42e-80, 1), 7, 11, 12, lower.tail=F, log.p=F)
+[1] 7 7 6 5 4 1 1
+
+##com.oracle.truffle.r.test.library.stats.TestDistributions.testQuantileFunctions#Output.MayIgnoreWarningContext#
+#qhyper(c(0, 42e-80, 0.1, 0.5, 0.7, 1-42e-80, 1), 7, 11, 12, lower.tail=T, log.p=F)
+[1] 1 1 3 5 5 7 7
+
+##com.oracle.truffle.r.test.library.stats.TestDistributions.testQuantileFunctions#Output.MayIgnoreWarningContext#
+#qhyper(c(0, 42e-80, 0.1, 0.5, 0.7, 1-42e-80, 1), 7, 11, 4, lower.tail=F, log.p=F)
+[1] 4 4 3 2 1 0 0
+
+##com.oracle.truffle.r.test.library.stats.TestDistributions.testQuantileFunctions#Output.MayIgnoreWarningContext#
+#qhyper(c(0, 42e-80, 0.1, 0.5, 0.7, 1-42e-80, 1), 7, 11, 4, lower.tail=T, log.p=F)
+[1] 0 0 0 2 2 4 4
+
+##com.oracle.truffle.r.test.library.stats.TestDistributions.testQuantileFunctions#Output.MayIgnoreWarningContext#
+#qhyper(c(0, 42e-80, 0.1, 0.5, 0.7, 1-42e-80, 1), 7e12, 11, 4, lower.tail=F, log.p=F)
+[1] 4 4 4 4 4 0 0
+
+##com.oracle.truffle.r.test.library.stats.TestDistributions.testQuantileFunctions#Output.MayIgnoreWarningContext#
+#qhyper(c(0, 42e-80, 0.1, 0.5, 0.7, 1-42e-80, 1), 7e12, 11, 4, lower.tail=T, log.p=F)
+[1] 0 0 4 4 4 4 4
+
+##com.oracle.truffle.r.test.library.stats.TestDistributions.testQuantileFunctions#Output.MayIgnoreWarningContext#
+#qhyper(log(c(0, 42e-80, 0.1, 0.5, 0.7, 1-42e-80, 1)), 11, 7e12, 7, lower.tail=F, log.p=T)
+[1] NaN   1   0   0   0   0   0
+Warning message:
+In qhyper(log(c(0, 4.2e-79, 0.1, 0.5, 0.7, 1 - 4.2e-79, 1)), 11,  :
+  NaNs produced
+
+##com.oracle.truffle.r.test.library.stats.TestDistributions.testQuantileFunctions#Output.MayIgnoreWarningContext#
+#qhyper(log(c(0, 42e-80, 0.1, 0.5, 0.7, 1-42e-80, 1)), 11, 7e12, 7, lower.tail=T, log.p=T)
+[1] NaN   0   0   0   0   7   7
+Warning message:
+In qhyper(log(c(0, 4.2e-79, 0.1, 0.5, 0.7, 1 - 4.2e-79, 1)), 11,  :
+  NaNs produced
+
+##com.oracle.truffle.r.test.library.stats.TestDistributions.testQuantileFunctions#Output.MayIgnoreWarningContext#
+#qhyper(log(c(0, 42e-80, 0.1, 0.5, 0.7, 1-42e-80, 1)), 3, 4, 10, lower.tail=F, log.p=T)
+[1] NaN NaN NaN NaN NaN NaN NaN
+Warning message:
+In qhyper(log(c(0, 4.2e-79, 0.1, 0.5, 0.7, 1 - 4.2e-79, 1)), 3,  :
+  NaNs produced
+
+##com.oracle.truffle.r.test.library.stats.TestDistributions.testQuantileFunctions#Output.MayIgnoreWarningContext#
+#qhyper(log(c(0, 42e-80, 0.1, 0.5, 0.7, 1-42e-80, 1)), 3, 4, 10, lower.tail=T, log.p=T)
+[1] NaN NaN NaN NaN NaN NaN NaN
+Warning message:
+In qhyper(log(c(0, 4.2e-79, 0.1, 0.5, 0.7, 1 - 4.2e-79, 1)), 3,  :
+  NaNs produced
+
+##com.oracle.truffle.r.test.library.stats.TestDistributions.testQuantileFunctions#Output.MayIgnoreWarningContext#
+#qhyper(log(c(0, 42e-80, 0.1, 0.5, 0.7, 1-42e-80, 1)), 5, 5, 5, lower.tail=F, log.p=T)
+[1] NaN   5   4   2   2   0   0
+Warning message:
+In qhyper(log(c(0, 4.2e-79, 0.1, 0.5, 0.7, 1 - 4.2e-79, 1)), 5,  :
+  NaNs produced
+
+##com.oracle.truffle.r.test.library.stats.TestDistributions.testQuantileFunctions#Output.MayIgnoreWarningContext#
+#qhyper(log(c(0, 42e-80, 0.1, 0.5, 0.7, 1-42e-80, 1)), 5, 5, 5, lower.tail=T, log.p=T)
+[1] NaN   0   1   2   3   5   5
+Warning message:
+In qhyper(log(c(0, 4.2e-79, 0.1, 0.5, 0.7, 1 - 4.2e-79, 1)), 5,  :
+  NaNs produced
+
+##com.oracle.truffle.r.test.library.stats.TestDistributions.testQuantileFunctions#Output.MayIgnoreWarningContext#
+#qhyper(log(c(0, 42e-80, 0.1, 0.5, 0.7, 1-42e-80, 1)), 7, 11, 12, lower.tail=F, log.p=T)
+[1] NaN   7   6   5   4   1   1
+Warning message:
+In qhyper(log(c(0, 4.2e-79, 0.1, 0.5, 0.7, 1 - 4.2e-79, 1)), 7,  :
+  NaNs produced
+
+##com.oracle.truffle.r.test.library.stats.TestDistributions.testQuantileFunctions#Output.MayIgnoreWarningContext#
+#qhyper(log(c(0, 42e-80, 0.1, 0.5, 0.7, 1-42e-80, 1)), 7, 11, 12, lower.tail=T, log.p=T)
+[1] NaN   1   3   5   5   7   7
+Warning message:
+In qhyper(log(c(0, 4.2e-79, 0.1, 0.5, 0.7, 1 - 4.2e-79, 1)), 7,  :
+  NaNs produced
+
+##com.oracle.truffle.r.test.library.stats.TestDistributions.testQuantileFunctions#Output.MayIgnoreWarningContext#
+#qhyper(log(c(0, 42e-80, 0.1, 0.5, 0.7, 1-42e-80, 1)), 7, 11, 4, lower.tail=F, log.p=T)
+[1] NaN   4   3   2   1   0   0
+Warning message:
+In qhyper(log(c(0, 4.2e-79, 0.1, 0.5, 0.7, 1 - 4.2e-79, 1)), 7,  :
+  NaNs produced
+
+##com.oracle.truffle.r.test.library.stats.TestDistributions.testQuantileFunctions#Output.MayIgnoreWarningContext#
+#qhyper(log(c(0, 42e-80, 0.1, 0.5, 0.7, 1-42e-80, 1)), 7, 11, 4, lower.tail=T, log.p=T)
+[1] NaN   0   0   2   2   4   4
+Warning message:
+In qhyper(log(c(0, 4.2e-79, 0.1, 0.5, 0.7, 1 - 4.2e-79, 1)), 7,  :
+  NaNs produced
+
+##com.oracle.truffle.r.test.library.stats.TestDistributions.testQuantileFunctions#Output.MayIgnoreWarningContext#
+#qhyper(log(c(0, 42e-80, 0.1, 0.5, 0.7, 1-42e-80, 1)), 7e12, 11, 4, lower.tail=F, log.p=T)
+[1] NaN   4   4   4   4   0   0
+Warning message:
+In qhyper(log(c(0, 4.2e-79, 0.1, 0.5, 0.7, 1 - 4.2e-79, 1)), 7e+12,  :
+  NaNs produced
+
+##com.oracle.truffle.r.test.library.stats.TestDistributions.testQuantileFunctions#Output.MayIgnoreWarningContext#
+#qhyper(log(c(0, 42e-80, 0.1, 0.5, 0.7, 1-42e-80, 1)), 7e12, 11, 4, lower.tail=T, log.p=T)
+[1] NaN   0   4   4   4   4   4
+Warning message:
+In qhyper(log(c(0, 4.2e-79, 0.1, 0.5, 0.7, 1 - 4.2e-79, 1)), 7e+12,  :
+  NaNs produced
+
+##com.oracle.truffle.r.test.library.stats.TestDistributions.testQuantileFunctions#Output.MayIgnoreWarningContext#
+#qnorm(-0.42e-38, 0, -1)
+[1] NaN
+Warning message:
+In qnorm(-4.2e-39, 0, -1) : NaNs produced
+
+##com.oracle.truffle.r.test.library.stats.TestDistributions.testQuantileFunctions#Output.MayIgnoreWarningContext#
+#qnorm(-42, 0, -1)
+[1] NaN
+Warning message:
+In qnorm(-42, 0, -1) : NaNs produced
+
+##com.oracle.truffle.r.test.library.stats.TestDistributions.testQuantileFunctions#Output.MayIgnoreWarningContext#
+#qnorm(-Inf, 0, -1)
+[1] NaN
+Warning message:
+In qnorm(-Inf, 0, -1) : NaNs produced
+
+##com.oracle.truffle.r.test.library.stats.TestDistributions.testQuantileFunctions#Output.MayIgnoreWarningContext#
+#qnorm(0, -Inf,  -1)
+[1] -Inf
+
+##com.oracle.truffle.r.test.library.stats.TestDistributions.testQuantileFunctions#Output.MayIgnoreWarningContext#
+#qnorm(0, 0, -Inf)
+[1] -Inf
+
+##com.oracle.truffle.r.test.library.stats.TestDistributions.testQuantileFunctions#Output.MayIgnoreWarningContext#
+#qnorm(0, 0, Inf)
+[1] -Inf
+
+##com.oracle.truffle.r.test.library.stats.TestDistributions.testQuantileFunctions#Output.MayIgnoreWarningContext#
+#qnorm(0, 0, NaN)
+[1] NaN
+
+##com.oracle.truffle.r.test.library.stats.TestDistributions.testQuantileFunctions#Output.MayIgnoreWarningContext#
+#qnorm(0, Inf,  -1)
+[1] -Inf
+
+##com.oracle.truffle.r.test.library.stats.TestDistributions.testQuantileFunctions#Output.MayIgnoreWarningContext#
+#qnorm(0, NaN,  -1)
+[1] NaN
+
+##com.oracle.truffle.r.test.library.stats.TestDistributions.testQuantileFunctions#Output.MayIgnoreWarningContext#
+#qnorm(Inf, 0, -1)
+[1] NaN
+Warning message:
+In qnorm(Inf, 0, -1) : NaNs produced
+
+##com.oracle.truffle.r.test.library.stats.TestDistributions.testQuantileFunctions#Output.MayIgnoreWarningContext#
+#qnorm(NaN, 0, -1)
+[1] NaN
+
+##com.oracle.truffle.r.test.library.stats.TestDistributions.testQuantileFunctions#Output.MayIgnoreWarningContext#
+#qnorm(c(0, 42e-80, 0.1, 0.5, 0.7, 1-42e-80, 1), 0, -1, lower.tail=F, log.p=F)
+[1]  Inf  NaN  NaN  NaN  NaN -Inf -Inf
+Warning message:
+In qnorm(c(0, 4.2e-79, 0.1, 0.5, 0.7, 1 - 4.2e-79, 1), 0, -1, lower.tail = F,  :
+  NaNs produced
+
+##com.oracle.truffle.r.test.library.stats.TestDistributions.testQuantileFunctions#Output.MayIgnoreWarningContext#
+#qnorm(c(0, 42e-80, 0.1, 0.5, 0.7, 1-42e-80, 1), 0, -1, lower.tail=T, log.p=F)
+[1] -Inf  NaN  NaN  NaN  NaN  Inf  Inf
+Warning message:
+In qnorm(c(0, 4.2e-79, 0.1, 0.5, 0.7, 1 - 4.2e-79, 1), 0, -1, lower.tail = T,  :
+  NaNs produced
+
+##com.oracle.truffle.r.test.library.stats.TestDistributions.testQuantileFunctions#Output.MayIgnoreWarningContext#
+#qnorm(c(0, 42e-80, 0.1, 0.5, 0.7, 1-42e-80, 1), 0, 0, lower.tail=F, log.p=F)
+[1]  Inf    0    0    0    0 -Inf -Inf
+
+##com.oracle.truffle.r.test.library.stats.TestDistributions.testQuantileFunctions#Output.MayIgnoreWarningContext#
+#qnorm(c(0, 42e-80, 0.1, 0.5, 0.7, 1-42e-80, 1), 0, 0, lower.tail=T, log.p=F)
+[1] -Inf    0    0    0    0  Inf  Inf
+
+##com.oracle.truffle.r.test.library.stats.TestDistributions.testQuantileFunctions#Output.MayIgnoreWarningContext#
+#qnorm(c(0, 42e-80, 0.1, 0.5, 0.7, 1-42e-80, 1), 4, 4, lower.tail=F, log.p=F)
+[1]       Inf 79.177408  9.126206  4.000000  1.902398      -Inf      -Inf
+
+##com.oracle.truffle.r.test.library.stats.TestDistributions.testQuantileFunctions#Output.MayIgnoreWarningContext#
+#qnorm(c(0, 42e-80, 0.1, 0.5, 0.7, 1-42e-80, 1), 4, 4, lower.tail=T, log.p=F)
+[1]       -Inf -71.177408  -1.126206   4.000000   6.097602        Inf        Inf
+
+##com.oracle.truffle.r.test.library.stats.TestDistributions.testQuantileFunctions#Output.MayIgnoreWarningContext#
+#qnorm(log(c(0, 42e-80, 0.1, 0.5, 0.7, 1-42e-80, 1)), 0, -1, lower.tail=F, log.p=T)
+[1]  Inf  NaN  NaN  NaN  NaN -Inf -Inf
+Warning message:
+In qnorm(log(c(0, 4.2e-79, 0.1, 0.5, 0.7, 1 - 4.2e-79, 1)), 0, -1,  :
+  NaNs produced
+
+##com.oracle.truffle.r.test.library.stats.TestDistributions.testQuantileFunctions#Output.MayIgnoreWarningContext#
+#qnorm(log(c(0, 42e-80, 0.1, 0.5, 0.7, 1-42e-80, 1)), 0, -1, lower.tail=T, log.p=T)
+[1] -Inf  NaN  NaN  NaN  NaN  Inf  Inf
+Warning message:
+In qnorm(log(c(0, 4.2e-79, 0.1, 0.5, 0.7, 1 - 4.2e-79, 1)), 0, -1,  :
+  NaNs produced
+
+##com.oracle.truffle.r.test.library.stats.TestDistributions.testQuantileFunctions#Output.MayIgnoreWarningContext#
+#qnorm(log(c(0, 42e-80, 0.1, 0.5, 0.7, 1-42e-80, 1)), 0, 0, lower.tail=F, log.p=T)
+[1]  Inf    0    0    0    0 -Inf -Inf
+
+##com.oracle.truffle.r.test.library.stats.TestDistributions.testQuantileFunctions#Output.MayIgnoreWarningContext#
+#qnorm(log(c(0, 42e-80, 0.1, 0.5, 0.7, 1-42e-80, 1)), 0, 0, lower.tail=T, log.p=T)
+[1] -Inf    0    0    0    0  Inf  Inf
+
+##com.oracle.truffle.r.test.library.stats.TestDistributions.testQuantileFunctions#Output.MayIgnoreWarningContext#
+#qnorm(log(c(0, 42e-80, 0.1, 0.5, 0.7, 1-42e-80, 1)), 4, 4, lower.tail=F, log.p=T)
+[1]       Inf 79.177408  9.126206  4.000000  1.902398      -Inf      -Inf
+
+##com.oracle.truffle.r.test.library.stats.TestDistributions.testQuantileFunctions#Output.MayIgnoreWarningContext#
+#qnorm(log(c(0, 42e-80, 0.1, 0.5, 0.7, 1-42e-80, 1)), 4, 4, lower.tail=T, log.p=T)
+[1]       -Inf -71.177408  -1.126206   4.000000   6.097602        Inf        Inf
+
+##com.oracle.truffle.r.test.library.stats.TestDistributions.testQuantileFunctions#Output.MayIgnoreWarningContext#
+#qunif(-0.42e-38, -3, 3.3)
+[1] NaN
+Warning message:
+In qunif(-4.2e-39, -3, 3.3) : NaNs produced
+
+##com.oracle.truffle.r.test.library.stats.TestDistributions.testQuantileFunctions#Output.MayIgnoreWarningContext#
+#qunif(-42, -3, 3.3)
+[1] NaN
+Warning message:
+In qunif(-42, -3, 3.3) : NaNs produced
+
+##com.oracle.truffle.r.test.library.stats.TestDistributions.testQuantileFunctions#Output.MayIgnoreWarningContext#
+#qunif(-Inf, -3, 3.3)
+[1] NaN
+Warning message:
+In qunif(-Inf, -3, 3.3) : NaNs produced
+
+##com.oracle.truffle.r.test.library.stats.TestDistributions.testQuantileFunctions#Output.MayIgnoreWarningContext#
+#qunif(0, -3, -Inf)
+[1] NaN
+Warning message:
+In qunif(0, -3, -Inf) : NaNs produced
+
+##com.oracle.truffle.r.test.library.stats.TestDistributions.testQuantileFunctions#Output.MayIgnoreWarningContext#
+#qunif(0, -3, Inf)
+[1] NaN
+Warning message:
+In qunif(0, -3, Inf) : NaNs produced
+
+##com.oracle.truffle.r.test.library.stats.TestDistributions.testQuantileFunctions#Output.MayIgnoreWarningContext#
+#qunif(0, -3, NaN)
+[1] NaN
+
+##com.oracle.truffle.r.test.library.stats.TestDistributions.testQuantileFunctions#Output.MayIgnoreWarningContext#
+#qunif(0, -Inf,  3.3)
+[1] NaN
+Warning message:
+In qunif(0, -Inf, 3.3) : NaNs produced
+
+##com.oracle.truffle.r.test.library.stats.TestDistributions.testQuantileFunctions#Output.MayIgnoreWarningContext#
+#qunif(0, Inf,  3.3)
+[1] NaN
+Warning message:
+In qunif(0, Inf, 3.3) : NaNs produced
+
+##com.oracle.truffle.r.test.library.stats.TestDistributions.testQuantileFunctions#Output.MayIgnoreWarningContext#
+#qunif(0, NaN,  3.3)
+[1] NaN
+
+##com.oracle.truffle.r.test.library.stats.TestDistributions.testQuantileFunctions#Output.MayIgnoreWarningContext#
+#qunif(Inf, -3, 3.3)
+[1] NaN
+Warning message:
+In qunif(Inf, -3, 3.3) : NaNs produced
+
+##com.oracle.truffle.r.test.library.stats.TestDistributions.testQuantileFunctions#Output.MayIgnoreWarningContext#
+#qunif(NaN, -3, 3.3)
+[1] NaN
+
+##com.oracle.truffle.r.test.library.stats.TestDistributions.testQuantileFunctions#Output.MayIgnoreWarningContext#
+#qunif(c(0, 42e-80, 0.1, 0.5, 0.7, 1-42e-80, 1), -3, 3.3, lower.tail=F, log.p=F)
+[1]  3.30  3.30  2.67  0.15 -1.11 -3.00 -3.00
+
+##com.oracle.truffle.r.test.library.stats.TestDistributions.testQuantileFunctions#Output.MayIgnoreWarningContext#
+#qunif(c(0, 42e-80, 0.1, 0.5, 0.7, 1-42e-80, 1), -3, 3.3, lower.tail=T, log.p=F)
+[1] -3.00 -3.00 -2.37  0.15  1.41  3.30  3.30
+
+##com.oracle.truffle.r.test.library.stats.TestDistributions.testQuantileFunctions#Output.MayIgnoreWarningContext#
+#qunif(log(c(0, 42e-80, 0.1, 0.5, 0.7, 1-42e-80, 1)), -3, 3.3, lower.tail=F, log.p=T)
+[1]  3.30  3.30  2.67  0.15 -1.11 -3.00 -3.00
+
+##com.oracle.truffle.r.test.library.stats.TestDistributions.testQuantileFunctions#Output.MayIgnoreWarningContext#
+#qunif(log(c(0, 42e-80, 0.1, 0.5, 0.7, 1-42e-80, 1)), -3, 3.3, lower.tail=T, log.p=T)
+[1] -3.00 -3.00 -2.37  0.15  1.41  3.30  3.30
+
 ##com.oracle.truffle.r.test.library.stats.TestExternal_covcor.testCovcor#
 #.Call(stats:::C_cov, 1:5, 1:5, 4, FALSE)
 [1] 2.5
@@ -111368,7 +115142,7 @@ In rbinom("aa", 10, 0.5) : NAs introduced by coercion
 #set.seed(42); rbinom(c(1,2), 11:12, c(0.1, 0.5, 0.9))
 [1] 3 9
 
-##com.oracle.truffle.r.test.library.stats.TestExternal_rnbinom.testRbinomWithMu#Ignored.Unimplemented#
+##com.oracle.truffle.r.test.library.stats.TestExternal_rnbinom.testRbinomWithMu#Ignored.Unstable#
 #set.seed(42); rnbinom(100, c(-1, 0, 1, 0.8, 10, NA, NaN, 1/0, -1/0), mu=c(-1, 0, 1, 0.8, 3, 10, NA, NaN, 1/0, -1/0))
   [1] NaN NaN   1   1   4 NaN NaN NaN NaN NaN NaN   0   0   0 NaN NaN NaN NaN
  [19] NaN NaN NaN   0   0 NaN NaN   5 NaN NaN NaN NaN NaN   0 NaN NaN   5 NaN
@@ -114289,48 +118063,6 @@ In dchisq(c(-1, 0, 0.2, 2), rep(c(-1, 0, 0.1, 0.9, 3), 4), log = TRUE) :
 #set.seed(1); dchisq(c(NA, 0, NaN, 1/0, -1/0), rep(c(1, 0, 0.1), 5), log=FALSE)
  [1]  NA Inf NaN   0   0  NA Inf NaN   0   0  NA Inf NaN   0   0
 
-##com.oracle.truffle.r.test.library.stats.TestStatFunctions.testFunctions21#Output.IgnoreWhitespace#
-#set.seed(1); dexp(0, c(0.0653, 0.000123, 32e-80, 8833, 79e70, 0, -1), log=FALSE)
-[1] 6.530e-02 1.230e-04 3.200e-79 8.833e+03 7.900e+71 0.000e+00       NaN
-Warning message:
-In dexp(0, c(0.0653, 0.000123, 3.2e-79, 8833, 7.9e+71, 0, -1), log = FALSE) :
-  NaNs produced
-
-##com.oracle.truffle.r.test.library.stats.TestStatFunctions.testFunctions21#Output.IgnoreWhitespace#
-#set.seed(1); dexp(10, 10, log=TRUE)
-[1] -97.69741
-
-##com.oracle.truffle.r.test.library.stats.TestStatFunctions.testFunctions21#Output.IgnoreWhitespace#
-#set.seed(1); dexp(3, 3, log=FALSE)
-[1] 0.0003702294
-
-##com.oracle.truffle.r.test.library.stats.TestStatFunctions.testFunctions21#Output.IgnoreWhitespace#
-#set.seed(1); dexp(c(-1, 0, 0.2, 2), rep(c(-1, 0, 0.1, 0.9, 3), 4), log=FALSE)
- [1]         NaN 0.000000000 0.098019867 0.148768999 0.000000000         NaN
- [7] 0.000000000 0.081873075 0.000000000 3.000000000         NaN 0.000000000
-[13] 0.000000000 0.900000000 1.646434908         NaN 0.000000000 0.100000000
-[19] 0.751743190 0.007436257
-Warning message:
-In dexp(c(-1, 0, 0.2, 2), rep(c(-1, 0, 0.1, 0.9, 3), 4), log = FALSE) :
-  NaNs produced
-
-##com.oracle.truffle.r.test.library.stats.TestStatFunctions.testFunctions21#Output.IgnoreWhitespace#
-#set.seed(1); dexp(c(-1, 0, 0.2, 2), rep(c(-1, 0, 0.1, 0.9, 3), 4), log=TRUE)
- [1]        NaN       -Inf -2.3225851 -1.9053605       -Inf        NaN
- [7]       -Inf -2.5025851       -Inf  1.0986123        NaN       -Inf
-[13]       -Inf -0.1053605  0.4986123        NaN       -Inf -2.3025851
-[19] -0.2853605 -4.9013877
-Warning message:
-In dexp(c(-1, 0, 0.2, 2), rep(c(-1, 0, 0.1, 0.9, 3), 4), log = TRUE) :
-  NaNs produced
-
-##com.oracle.truffle.r.test.library.stats.TestStatFunctions.testFunctions21#Output.IgnoreWhitespace#
-#set.seed(1); dexp(c(NA, 0, NaN, 1/0, -1/0), rep(c(1, 0, 0.1), 5), log=FALSE)
- [1]  NA 0.0 NaN 0.0 0.0  NA 1.0 NaN 0.0 0.0  NA 0.1 NaN NaN 0.0
-Warning message:
-In dexp(c(NA, 0, NaN, 1/0, -1/0), rep(c(1, 0, 0.1), 5), log = FALSE) :
-  NaNs produced
-
 ##com.oracle.truffle.r.test.library.stats.TestStatFunctions.testFunctions21#Output.IgnoreWhitespace#
 #set.seed(1); dgeom(0, c(0.0653, 0.000123, 32e-80, 8833, 79e70, 0, -1), log=FALSE)
 [1] 6.53e-02 1.23e-04 3.20e-79      NaN      NaN      NaN      NaN
@@ -114582,191 +118314,387 @@ Warning messages:
   NaNs produced
 
 ##com.oracle.truffle.r.test.library.stats.TestStatFunctions.testFunctions22#Output.IgnoreWhitespace#
-#set.seed(1); pexp(0, 10, lower.tail=FALSE, log.p=FALSE)
-[1] 1
+#set.seed(1); pgeom(0, 10, lower.tail=FALSE, log.p=FALSE)
+[1] NaN
+Warning message:
+In pgeom(0, 10, lower.tail = FALSE, log.p = FALSE) : NaNs produced
 
 ##com.oracle.truffle.r.test.library.stats.TestStatFunctions.testFunctions22#Output.IgnoreWhitespace#
-#set.seed(1); pexp(0, 10, lower.tail=FALSE, log.p=TRUE)
-[1] 0
+#set.seed(1); pgeom(0, 10, lower.tail=FALSE, log.p=TRUE)
+[1] NaN
+Warning message:
+In pgeom(0, 10, lower.tail = FALSE, log.p = TRUE) : NaNs produced
 
 ##com.oracle.truffle.r.test.library.stats.TestStatFunctions.testFunctions22#Output.IgnoreWhitespace#
-#set.seed(1); pexp(0, 10, lower.tail=TRUE, log.p=FALSE)
-[1] 0
+#set.seed(1); pgeom(0, 10, lower.tail=TRUE, log.p=FALSE)
+[1] NaN
+Warning message:
+In pgeom(0, 10, lower.tail = TRUE, log.p = FALSE) : NaNs produced
 
 ##com.oracle.truffle.r.test.library.stats.TestStatFunctions.testFunctions22#Output.IgnoreWhitespace#
-#set.seed(1); pexp(0, 10, lower.tail=TRUE, log.p=TRUE)
-[1] -Inf
+#set.seed(1); pgeom(0, 10, lower.tail=TRUE, log.p=TRUE)
+[1] NaN
+Warning message:
+In pgeom(0, 10, lower.tail = TRUE, log.p = TRUE) : NaNs produced
 
 ##com.oracle.truffle.r.test.library.stats.TestStatFunctions.testFunctions22#Output.IgnoreWhitespace#
-#set.seed(1); pexp(0, c(0.0653, 0.000123, 32e-80, 8833, 79e70, 0, -1), lower.tail=FALSE, log.p=FALSE)
-[1]   1   1   1   1   1   1 NaN
+#set.seed(1); pgeom(0, c(0.0653, 0.000123, 32e-80, 8833, 79e70, 0, -1), lower.tail=FALSE, log.p=FALSE)
+[1] 0.934700 0.999877 1.000000      NaN      NaN      NaN      NaN
 Warning message:
-In pexp(0, c(0.0653, 0.000123, 3.2e-79, 8833, 7.9e+71, 0, -1), lower.tail = FALSE,  :
+In pgeom(0, c(0.0653, 0.000123, 3.2e-79, 8833, 7.9e+71, 0, -1),  :
   NaNs produced
 
 ##com.oracle.truffle.r.test.library.stats.TestStatFunctions.testFunctions22#Output.IgnoreWhitespace#
-#set.seed(1); pexp(0, c(0.0653, 0.000123, 32e-80, 8833, 79e70, 0, -1), lower.tail=FALSE, log.p=TRUE)
-[1]   0   0   0   0   0   0 NaN
+#set.seed(1); pgeom(0, c(0.0653, 0.000123, 32e-80, 8833, 79e70, 0, -1), lower.tail=FALSE, log.p=TRUE)
+[1] -6.752966e-02 -1.230076e-04 -3.200000e-79           NaN           NaN
+[6]           NaN           NaN
 Warning message:
-In pexp(0, c(0.0653, 0.000123, 3.2e-79, 8833, 7.9e+71, 0, -1), lower.tail = FALSE,  :
+In pgeom(0, c(0.0653, 0.000123, 3.2e-79, 8833, 7.9e+71, 0, -1),  :
   NaNs produced
 
 ##com.oracle.truffle.r.test.library.stats.TestStatFunctions.testFunctions22#Output.IgnoreWhitespace#
-#set.seed(1); pexp(0, c(0.0653, 0.000123, 32e-80, 8833, 79e70, 0, -1), lower.tail=TRUE, log.p=FALSE)
-[1]   0   0   0   0   0   0 NaN
+#set.seed(1); pgeom(0, c(0.0653, 0.000123, 32e-80, 8833, 79e70, 0, -1), lower.tail=TRUE, log.p=FALSE)
+[1] 6.53e-02 1.23e-04 3.20e-79      NaN      NaN      NaN      NaN
 Warning message:
-In pexp(0, c(0.0653, 0.000123, 3.2e-79, 8833, 7.9e+71, 0, -1), lower.tail = TRUE,  :
+In pgeom(0, c(0.0653, 0.000123, 3.2e-79, 8833, 7.9e+71, 0, -1),  :
   NaNs produced
 
 ##com.oracle.truffle.r.test.library.stats.TestStatFunctions.testFunctions22#Output.IgnoreWhitespace#
-#set.seed(1); pexp(0, c(0.0653, 0.000123, 32e-80, 8833, 79e70, 0, -1), lower.tail=TRUE, log.p=TRUE)
-[1] -Inf -Inf -Inf -Inf -Inf -Inf  NaN
+#set.seed(1); pgeom(0, c(0.0653, 0.000123, 32e-80, 8833, 79e70, 0, -1), lower.tail=TRUE, log.p=TRUE)
+[1]   -2.728763   -9.003326 -180.741072         NaN         NaN         NaN
+[7]         NaN
 Warning message:
-In pexp(0, c(0.0653, 0.000123, 3.2e-79, 8833, 7.9e+71, 0, -1), lower.tail = TRUE,  :
+In pgeom(0, c(0.0653, 0.000123, 3.2e-79, 8833, 7.9e+71, 0, -1),  :
   NaNs produced
 
 ##com.oracle.truffle.r.test.library.stats.TestStatFunctions.testFunctions22#Output.IgnoreWhitespace#
-#set.seed(1); pexp(c(-1, 0, 0.2, 2), rep(c(-1, 0, 0.1, 0.9, 3), 4), lower.tail=FALSE, log.p=FALSE)
- [1]         NaN 1.000000000 0.980198673 0.165298888 1.000000000         NaN
- [7] 1.000000000 0.818730753 1.000000000 1.000000000         NaN 1.000000000
-[13] 1.000000000 1.000000000 0.548811636         NaN 1.000000000 1.000000000
-[19] 0.835270211 0.002478752
+#set.seed(1); pgeom(c(-1, 0, 0.2, 2), rep(c(-1, 0, 0.1, 0.9, 3), 4), lower.tail=FALSE, log.p=FALSE)
+ [1]   NaN   NaN 0.900 0.001   NaN   NaN   NaN 0.729 1.000   NaN   NaN   NaN
+[13] 1.000 0.100   NaN   NaN   NaN 0.900 0.100   NaN
 Warning message:
-In pexp(c(-1, 0, 0.2, 2), rep(c(-1, 0, 0.1, 0.9, 3), 4), lower.tail = FALSE,  :
+In pgeom(c(-1, 0, 0.2, 2), rep(c(-1, 0, 0.1, 0.9, 3), 4), lower.tail = FALSE,  :
   NaNs produced
 
 ##com.oracle.truffle.r.test.library.stats.TestStatFunctions.testFunctions22#Output.IgnoreWhitespace#
-#set.seed(1); pexp(c(-1, 0, 0.2, 2), rep(c(-1, 0, 0.1, 0.9, 3), 4), lower.tail=FALSE, log.p=TRUE)
- [1]   NaN  0.00 -0.02 -1.80  0.00   NaN  0.00 -0.20  0.00  0.00   NaN  0.00
-[13]  0.00  0.00 -0.60   NaN  0.00  0.00 -0.18 -6.00
+#set.seed(1); pgeom(c(-1, 0, 0.2, 2), rep(c(-1, 0, 0.1, 0.9, 3), 4), lower.tail=FALSE, log.p=TRUE)
+ [1]        NaN        NaN -0.1053605 -6.9077553        NaN        NaN
+ [7]        NaN -0.3160815  0.0000000        NaN        NaN        NaN
+[13]  0.0000000 -2.3025851        NaN        NaN        NaN -0.1053605
+[19] -2.3025851        NaN
 Warning message:
-In pexp(c(-1, 0, 0.2, 2), rep(c(-1, 0, 0.1, 0.9, 3), 4), lower.tail = FALSE,  :
+In pgeom(c(-1, 0, 0.2, 2), rep(c(-1, 0, 0.1, 0.9, 3), 4), lower.tail = FALSE,  :
   NaNs produced
 
 ##com.oracle.truffle.r.test.library.stats.TestStatFunctions.testFunctions22#Output.IgnoreWhitespace#
-#set.seed(1); pexp(c(-1, 0, 0.2, 2), rep(c(-1, 0, 0.1, 0.9, 3), 4), lower.tail=TRUE, log.p=FALSE)
- [1]        NaN 0.00000000 0.01980133 0.83470111 0.00000000        NaN
- [7] 0.00000000 0.18126925 0.00000000 0.00000000        NaN 0.00000000
-[13] 0.00000000 0.00000000 0.45118836        NaN 0.00000000 0.00000000
-[19] 0.16472979 0.99752125
+#set.seed(1); pgeom(c(-1, 0, 0.2, 2), rep(c(-1, 0, 0.1, 0.9, 3), 4), lower.tail=TRUE, log.p=FALSE)
+ [1]   NaN   NaN 0.100 0.999   NaN   NaN   NaN 0.271 0.000   NaN   NaN   NaN
+[13] 0.000 0.900   NaN   NaN   NaN 0.100 0.900   NaN
 Warning message:
-In pexp(c(-1, 0, 0.2, 2), rep(c(-1, 0, 0.1, 0.9, 3), 4), lower.tail = TRUE,  :
+In pgeom(c(-1, 0, 0.2, 2), rep(c(-1, 0, 0.1, 0.9, 3), 4), lower.tail = TRUE,  :
   NaNs produced
 
 ##com.oracle.truffle.r.test.library.stats.TestStatFunctions.testFunctions22#Output.IgnoreWhitespace#
-#set.seed(1); pexp(c(-1, 0, 0.2, 2), rep(c(-1, 0, 0.1, 0.9, 3), 4), lower.tail=TRUE, log.p=TRUE)
- [1]          NaN         -Inf -3.922006339 -0.180681568         -Inf
- [6]          NaN         -Inf -1.707771801         -Inf         -Inf
-[11]          NaN         -Inf         -Inf         -Inf -0.795870368
-[16]          NaN         -Inf         -Inf -1.803448792 -0.002481829
+#set.seed(1); pgeom(c(-1, 0, 0.2, 2), rep(c(-1, 0, 0.1, 0.9, 3), 4), lower.tail=TRUE, log.p=TRUE)
+ [1]        NaN        NaN -2.3025851 -0.0010005        NaN        NaN
+ [7]        NaN -1.3056365       -Inf        NaN        NaN        NaN
+[13]       -Inf -0.1053605        NaN        NaN        NaN -2.3025851
+[19] -0.1053605        NaN
 Warning message:
-In pexp(c(-1, 0, 0.2, 2), rep(c(-1, 0, 0.1, 0.9, 3), 4), lower.tail = TRUE,  :
+In pgeom(c(-1, 0, 0.2, 2), rep(c(-1, 0, 0.1, 0.9, 3), 4), lower.tail = TRUE,  :
   NaNs produced
 
 ##com.oracle.truffle.r.test.library.stats.TestStatFunctions.testFunctions22#Output.IgnoreWhitespace#
-#set.seed(1); pexp(c(NA, 0, NaN, 1/0, -1/0), rep(c(1, 0, 0.1), 5))
- [1]  NA   0 NaN   1   0  NA   0 NaN   1   0  NA   0 NaN NaN   0
+#set.seed(1); pgeom(c(NA, 0, NaN, 1/0, -1/0), rep(c(1, 0, 0.1), 5))
+ [1]  NA NaN NaN 1.0 NaN  NA 1.0 NaN 1.0 0.0  NA 0.1 NaN NaN 0.0
 Warning message:
-In pexp(c(NA, 0, NaN, 1/0, -1/0), rep(c(1, 0, 0.1), 5)) : NaNs produced
+In pgeom(c(NA, 0, NaN, 1/0, -1/0), rep(c(1, 0, 0.1), 5)) : NaNs produced
 
 ##com.oracle.truffle.r.test.library.stats.TestStatFunctions.testFunctions22#Output.IgnoreWhitespace#
-#set.seed(1); pexp(rep(c(1, 0, 0.1), 5), c(NA, 0, NaN, 1/0, -1/0))
- [1]   NA    0  NaN    1    0   NA    0  NaN    1 -Inf   NA    0  NaN    0 -Inf
+#set.seed(1); pgeom(rep(c(1, 0, 0.1), 5), c(NA, 0, NaN, 1/0, -1/0))
+ [1]  NA NaN NaN NaN NaN  NA NaN NaN NaN NaN  NA NaN NaN NaN NaN
+Warning message:
+In pgeom(rep(c(1, 0, 0.1), 5), c(NA, 0, NaN, 1/0, -1/0)) : NaNs produced
 
 ##com.oracle.truffle.r.test.library.stats.TestStatFunctions.testFunctions22#Output.IgnoreWhitespace#
-#set.seed(1); qexp(0, 10, lower.tail=FALSE, log.p=FALSE)
-[1] Inf
+#set.seed(1); ppois(0, 10, lower.tail=FALSE, log.p=FALSE)
+[1] 0.9999546
 
 ##com.oracle.truffle.r.test.library.stats.TestStatFunctions.testFunctions22#Output.IgnoreWhitespace#
-#set.seed(1); qexp(0, 10, lower.tail=FALSE, log.p=TRUE)
-[1] 0
+#set.seed(1); ppois(0, 10, lower.tail=FALSE, log.p=TRUE)
+[1] -4.540096e-05
 
 ##com.oracle.truffle.r.test.library.stats.TestStatFunctions.testFunctions22#Output.IgnoreWhitespace#
-#set.seed(1); qexp(0, 10, lower.tail=TRUE, log.p=FALSE)
-[1] 0
+#set.seed(1); ppois(0, 10, lower.tail=TRUE, log.p=FALSE)
+[1] 4.539993e-05
 
 ##com.oracle.truffle.r.test.library.stats.TestStatFunctions.testFunctions22#Output.IgnoreWhitespace#
-#set.seed(1); qexp(0, 10, lower.tail=TRUE, log.p=TRUE)
-[1] Inf
+#set.seed(1); ppois(0, 10, lower.tail=TRUE, log.p=TRUE)
+[1] -10
 
 ##com.oracle.truffle.r.test.library.stats.TestStatFunctions.testFunctions22#Output.IgnoreWhitespace#
-#set.seed(1); qexp(0, c(0.0653, 0.000123, 32e-80, 8833, 79e70, 0, -1), lower.tail=FALSE, log.p=FALSE)
-[1] Inf Inf Inf Inf Inf Inf NaN
+#set.seed(1); ppois(0, c(0.0653, 0.000123, 32e-80, 8833, 79e70, 0, -1), lower.tail=FALSE, log.p=FALSE)
+[1] 6.321361e-02 1.229924e-04 3.200000e-79 1.000000e+00 1.000000e+00
+[6] 0.000000e+00          NaN
 Warning message:
-In qexp(0, c(0.0653, 0.000123, 3.2e-79, 8833, 7.9e+71, 0, -1), lower.tail = FALSE,  :
+In ppois(0, c(0.0653, 0.000123, 3.2e-79, 8833, 7.9e+71, 0, -1),  :
   NaNs produced
 
 ##com.oracle.truffle.r.test.library.stats.TestStatFunctions.testFunctions22#Output.IgnoreWhitespace#
-#set.seed(1); qexp(0, c(0.0653, 0.000123, 32e-80, 8833, 79e70, 0, -1), lower.tail=FALSE, log.p=TRUE)
-[1]   0   0   0   0   0   0 NaN
+#set.seed(1); ppois(0, c(0.0653, 0.000123, 32e-80, 8833, 79e70, 0, -1), lower.tail=FALSE, log.p=TRUE)
+[1]   -2.761236   -9.003388 -180.741072    0.000000    0.000000        -Inf
+[7]         NaN
 Warning message:
-In qexp(0, c(0.0653, 0.000123, 3.2e-79, 8833, 7.9e+71, 0, -1), lower.tail = FALSE,  :
+In ppois(0, c(0.0653, 0.000123, 3.2e-79, 8833, 7.9e+71, 0, -1),  :
   NaNs produced
 
 ##com.oracle.truffle.r.test.library.stats.TestStatFunctions.testFunctions22#Output.IgnoreWhitespace#
-#set.seed(1); qexp(0, c(0.0653, 0.000123, 32e-80, 8833, 79e70, 0, -1), lower.tail=TRUE, log.p=FALSE)
-[1]   0   0   0   0   0   0 NaN
+#set.seed(1); ppois(0, c(0.0653, 0.000123, 32e-80, 8833, 79e70, 0, -1), lower.tail=TRUE, log.p=FALSE)
+[1] 0.9367864 0.9998770 1.0000000 0.0000000 0.0000000 1.0000000       NaN
 Warning message:
-In qexp(0, c(0.0653, 0.000123, 3.2e-79, 8833, 7.9e+71, 0, -1), lower.tail = TRUE,  :
+In ppois(0, c(0.0653, 0.000123, 3.2e-79, 8833, 7.9e+71, 0, -1),  :
   NaNs produced
 
 ##com.oracle.truffle.r.test.library.stats.TestStatFunctions.testFunctions22#Output.IgnoreWhitespace#
-#set.seed(1); qexp(0, c(0.0653, 0.000123, 32e-80, 8833, 79e70, 0, -1), lower.tail=TRUE, log.p=TRUE)
-[1] Inf Inf Inf Inf Inf Inf NaN
+#set.seed(1); ppois(0, c(0.0653, 0.000123, 32e-80, 8833, 79e70, 0, -1), lower.tail=TRUE, log.p=TRUE)
+[1] -6.530e-02 -1.230e-04 -3.200e-79 -8.833e+03 -7.900e+71  0.000e+00        NaN
 Warning message:
-In qexp(0, c(0.0653, 0.000123, 3.2e-79, 8833, 7.9e+71, 0, -1), lower.tail = TRUE,  :
+In ppois(0, c(0.0653, 0.000123, 3.2e-79, 8833, 7.9e+71, 0, -1),  :
   NaNs produced
 
 ##com.oracle.truffle.r.test.library.stats.TestStatFunctions.testFunctions22#Output.IgnoreWhitespace#
-#set.seed(1); qexp(c(-1, 0, 0.2, 2), rep(c(-1, 0, 0.1, 0.9, 3), 4), lower.tail=FALSE, log.p=FALSE)
- [1]        NaN        Inf 16.0943791        NaN        NaN        NaN
- [7]        Inf        NaN        NaN        Inf        NaN        NaN
-[13]        NaN        Inf  0.5364793        NaN        NaN        Inf
-[19]  1.7882643        NaN
+#set.seed(1); ppois(c(-1, 0, 0.2, 2), rep(c(-1, 0, 0.1, 0.9, 3), 4), lower.tail=FALSE, log.p=FALSE)
+ [1]          NaN 0.0000000000 0.0951625820 0.0628569343 1.0000000000
+ [6]          NaN 0.0000000000 0.0001546531 1.0000000000 0.9502129316
+[11]          NaN 0.0000000000 1.0000000000 0.5934303403 0.9502129316
+[16]          NaN 1.0000000000 0.0951625820 0.5934303403 0.5768099189
 Warning message:
-In qexp(c(-1, 0, 0.2, 2), rep(c(-1, 0, 0.1, 0.9, 3), 4), lower.tail = FALSE,  :
+In ppois(c(-1, 0, 0.2, 2), rep(c(-1, 0, 0.1, 0.9, 3), 4), lower.tail = FALSE,  :
   NaNs produced
 
 ##com.oracle.truffle.r.test.library.stats.TestStatFunctions.testFunctions22#Output.IgnoreWhitespace#
-#set.seed(1); qexp(c(-1, 0, 0.2, 2), rep(c(-1, 0, 0.1, 0.9, 3), 4), lower.tail=FALSE, log.p=TRUE)
- [1]        NaN  0.0000000        NaN        NaN  0.3333333        NaN
- [7]        NaN        NaN  1.1111111  0.0000000        NaN        NaN
-[13] 10.0000000  0.0000000        NaN        NaN        Inf  0.0000000
-[19]        NaN        NaN
+#set.seed(1); ppois(c(-1, 0, 0.2, 2), rep(c(-1, 0, 0.1, 0.9, 3), 4), lower.tail=FALSE, log.p=TRUE)
+ [1]         NaN        -Inf -2.35216846 -2.76689402  0.00000000         NaN
+ [7]        -Inf -8.77432621  0.00000000 -0.05106918         NaN        -Inf
+[13]  0.00000000 -0.52183544 -0.05106918         NaN  0.00000000 -2.35216846
+[19] -0.52183544 -0.55024250
 Warning message:
-In qexp(c(-1, 0, 0.2, 2), rep(c(-1, 0, 0.1, 0.9, 3), 4), lower.tail = FALSE,  :
+In ppois(c(-1, 0, 0.2, 2), rep(c(-1, 0, 0.1, 0.9, 3), 4), lower.tail = FALSE,  :
   NaNs produced
 
 ##com.oracle.truffle.r.test.library.stats.TestStatFunctions.testFunctions22#Output.IgnoreWhitespace#
-#set.seed(1); qexp(c(-1, 0, 0.2, 2), rep(c(-1, 0, 0.1, 0.9, 3), 4), lower.tail=TRUE, log.p=FALSE)
- [1]        NaN 0.00000000 2.23143551        NaN        NaN        NaN
- [7]        Inf        NaN        NaN 0.00000000        NaN        NaN
-[13]        NaN 0.00000000 0.07438118        NaN        NaN 0.00000000
-[19] 0.24793728        NaN
+#set.seed(1); ppois(c(-1, 0, 0.2, 2), rep(c(-1, 0, 0.1, 0.9, 3), 4), lower.tail=TRUE, log.p=FALSE)
+ [1]        NaN 1.00000000 0.90483742 0.93714307 0.00000000        NaN
+ [7] 1.00000000 0.99984535 0.00000000 0.04978707        NaN 1.00000000
+[13] 0.00000000 0.40656966 0.04978707        NaN 0.00000000 0.90483742
+[19] 0.40656966 0.42319008
 Warning message:
-In qexp(c(-1, 0, 0.2, 2), rep(c(-1, 0, 0.1, 0.9, 3), 4), lower.tail = TRUE,  :
+In ppois(c(-1, 0, 0.2, 2), rep(c(-1, 0, 0.1, 0.9, 3), 4), lower.tail = TRUE,  :
   NaNs produced
 
 ##com.oracle.truffle.r.test.library.stats.TestStatFunctions.testFunctions22#Output.IgnoreWhitespace#
-#set.seed(1); qexp(c(-1, 0, 0.2, 2), rep(c(-1, 0, 0.1, 0.9, 3), 4), lower.tail=TRUE, log.p=TRUE)
- [1]       NaN       Inf       NaN       NaN 0.1528917       NaN       NaN
- [8]       NaN 0.5096391       Inf       NaN       NaN 4.5867515       Inf
-[15]       NaN       NaN       Inf       Inf       NaN       NaN
+#set.seed(1); ppois(c(-1, 0, 0.2, 2), rep(c(-1, 0, 0.1, 0.9, 3), 4), lower.tail=TRUE, log.p=TRUE)
+ [1]          NaN  0.000000000 -0.100000000 -0.064919324         -Inf
+ [6]          NaN  0.000000000 -0.000154665         -Inf -3.000000000
+[11]          NaN  0.000000000         -Inf -0.900000000 -3.000000000
+[16]          NaN         -Inf -0.100000000 -0.900000000 -0.859933837
 Warning message:
-In qexp(c(-1, 0, 0.2, 2), rep(c(-1, 0, 0.1, 0.9, 3), 4), lower.tail = TRUE,  :
+In ppois(c(-1, 0, 0.2, 2), rep(c(-1, 0, 0.1, 0.9, 3), 4), lower.tail = TRUE,  :
   NaNs produced
 
 ##com.oracle.truffle.r.test.library.stats.TestStatFunctions.testFunctions22#Output.IgnoreWhitespace#
-#set.seed(1); qexp(c(NA, 0, NaN, 1/0, -1/0), rep(c(1, 0, 0.1), 5))
- [1]  NA   0 NaN NaN NaN  NA   0 NaN NaN NaN  NA   0 NaN NaN NaN
+#set.seed(1); ppois(c(NA, 0, NaN, 1/0, -1/0), rep(c(1, 0, 0.1), 5))
+ [1]        NA 1.0000000       NaN 1.0000000 0.0000000        NA 0.3678794
+ [8]       NaN 1.0000000 0.0000000        NA 0.9048374       NaN 1.0000000
+[15] 0.0000000
+
+##com.oracle.truffle.r.test.library.stats.TestStatFunctions.testFunctions22#Output.IgnoreWhitespace#
+#set.seed(1); ppois(rep(c(1, 0, 0.1), 5), c(NA, 0, NaN, 1/0, -1/0))
+ [1]  NA   1 NaN   0 NaN  NA   1 NaN   0 NaN  NA   1 NaN   0 NaN
+Warning message:
+In ppois(rep(c(1, 0, 0.1), 5), c(NA, 0, NaN, 1/0, -1/0)) : NaNs produced
+
+##com.oracle.truffle.r.test.library.stats.TestStatFunctions.testFunctions22#Output.IgnoreWhitespace#
+#set.seed(1); pt(0, 10, lower.tail=FALSE, log.p=FALSE)
+[1] 0.5
+
+##com.oracle.truffle.r.test.library.stats.TestStatFunctions.testFunctions22#Output.IgnoreWhitespace#
+#set.seed(1); pt(0, 10, lower.tail=FALSE, log.p=TRUE)
+[1] -0.6931472
+
+##com.oracle.truffle.r.test.library.stats.TestStatFunctions.testFunctions22#Output.IgnoreWhitespace#
+#set.seed(1); pt(0, 10, lower.tail=TRUE, log.p=FALSE)
+[1] 0.5
+
+##com.oracle.truffle.r.test.library.stats.TestStatFunctions.testFunctions22#Output.IgnoreWhitespace#
+#set.seed(1); pt(0, 10, lower.tail=TRUE, log.p=TRUE)
+[1] -0.6931472
+
+##com.oracle.truffle.r.test.library.stats.TestStatFunctions.testFunctions22#Output.IgnoreWhitespace#
+#set.seed(1); pt(0, c(0.0653, 0.000123, 32e-80, 8833, 79e70, 0, -1), lower.tail=FALSE, log.p=FALSE)
+[1] 0.5 0.5 0.5 0.5 0.5 NaN NaN
+Warning message:
+In pt(0, c(0.0653, 0.000123, 3.2e-79, 8833, 7.9e+71, 0, -1), lower.tail = FALSE,  :
+  NaNs produced
+
+##com.oracle.truffle.r.test.library.stats.TestStatFunctions.testFunctions22#Output.IgnoreWhitespace#
+#set.seed(1); pt(0, c(0.0653, 0.000123, 32e-80, 8833, 79e70, 0, -1), lower.tail=FALSE, log.p=TRUE)
+[1] -0.6931472 -0.6931472 -0.6931472 -0.6931472 -0.6931472        NaN        NaN
+Warning message:
+In pt(0, c(0.0653, 0.000123, 3.2e-79, 8833, 7.9e+71, 0, -1), lower.tail = FALSE,  :
+  NaNs produced
+
+##com.oracle.truffle.r.test.library.stats.TestStatFunctions.testFunctions22#Output.IgnoreWhitespace#
+#set.seed(1); pt(0, c(0.0653, 0.000123, 32e-80, 8833, 79e70, 0, -1), lower.tail=TRUE, log.p=FALSE)
+[1] 0.5 0.5 0.5 0.5 0.5 NaN NaN
+Warning message:
+In pt(0, c(0.0653, 0.000123, 3.2e-79, 8833, 7.9e+71, 0, -1), lower.tail = TRUE,  :
+  NaNs produced
+
+##com.oracle.truffle.r.test.library.stats.TestStatFunctions.testFunctions22#Output.IgnoreWhitespace#
+#set.seed(1); pt(0, c(0.0653, 0.000123, 32e-80, 8833, 79e70, 0, -1), lower.tail=TRUE, log.p=TRUE)
+[1] -0.6931472 -0.6931472 -0.6931472 -0.6931472 -0.6931472        NaN        NaN
+Warning message:
+In pt(0, c(0.0653, 0.000123, 3.2e-79, 8833, 7.9e+71, 0, -1), lower.tail = TRUE,  :
+  NaNs produced
+
+##com.oracle.truffle.r.test.library.stats.TestStatFunctions.testFunctions22#Output.IgnoreWhitespace#
+#set.seed(1); pt(c(-1, 0, 0.2, 2), rep(c(-1, 0, 0.1, 0.9, 3), 4), lower.tail=FALSE, log.p=FALSE)
+ [1]        NaN        NaN 0.47222678 0.15801721 0.80449889        NaN
+ [7]        NaN 0.38917711 0.74287641 0.50000000        NaN        NaN
+[13] 0.58367176 0.50000000 0.42713516        NaN        NaN 0.50000000
+[19] 0.43852072 0.06966298
+Warning message:
+In pt(c(-1, 0, 0.2, 2), rep(c(-1, 0, 0.1, 0.9, 3), 4), lower.tail = FALSE,  :
+  NaNs produced
+
+##com.oracle.truffle.r.test.library.stats.TestStatFunctions.testFunctions22#Output.IgnoreWhitespace#
+#set.seed(1); pt(c(-1, 0, 0.2, 2), rep(c(-1, 0, 0.1, 0.9, 3), 4), lower.tail=FALSE, log.p=TRUE)
+ [1]        NaN        NaN -0.7502959 -1.8450513 -0.2175357        NaN
+ [7]        NaN -0.9437207 -0.2972256 -0.6931472        NaN        NaN
+[13] -0.5384165 -0.6931472 -0.8506548        NaN        NaN -0.6931472
+[19] -0.8243482 -2.6640862
+Warning message:
+In pt(c(-1, 0, 0.2, 2), rep(c(-1, 0, 0.1, 0.9, 3), 4), lower.tail = FALSE,  :
+  NaNs produced
+
+##com.oracle.truffle.r.test.library.stats.TestStatFunctions.testFunctions22#Output.IgnoreWhitespace#
+#set.seed(1); pt(c(-1, 0, 0.2, 2), rep(c(-1, 0, 0.1, 0.9, 3), 4), lower.tail=TRUE, log.p=FALSE)
+ [1]       NaN       NaN 0.5277732 0.8419828 0.1955011       NaN       NaN
+ [8] 0.6108229 0.2571236 0.5000000       NaN       NaN 0.4163282 0.5000000
+[15] 0.5728648       NaN       NaN 0.5000000 0.5614793 0.9303370
+Warning message:
+In pt(c(-1, 0, 0.2, 2), rep(c(-1, 0, 0.1, 0.9, 3), 4), lower.tail = TRUE,  :
+  NaNs produced
+
+##com.oracle.truffle.r.test.library.stats.TestStatFunctions.testFunctions22#Output.IgnoreWhitespace#
+#set.seed(1); pt(c(-1, 0, 0.2, 2), rep(c(-1, 0, 0.1, 0.9, 3), 4), lower.tail=TRUE, log.p=TRUE)
+ [1]         NaN         NaN -0.63908859 -0.17199570 -1.63218922         NaN
+ [7]         NaN -0.49294824 -1.35819841 -0.69314718         NaN         NaN
+[13] -0.87628129 -0.69314718 -0.55710548         NaN         NaN -0.69314718
+[19] -0.57718041 -0.07220838
+Warning message:
+In pt(c(-1, 0, 0.2, 2), rep(c(-1, 0, 0.1, 0.9, 3), 4), lower.tail = TRUE,  :
+  NaNs produced
+
+##com.oracle.truffle.r.test.library.stats.TestStatFunctions.testFunctions22#Output.IgnoreWhitespace#
+#set.seed(1); pt(c(NA, 0, NaN, 1/0, -1/0), rep(c(1, 0, 0.1), 5))
+ [1]  NA NaN NaN 1.0 NaN  NA 0.5 NaN 1.0 0.0  NA 0.5 NaN NaN 0.0
 Warning message:
-In qexp(c(NA, 0, NaN, 1/0, -1/0), rep(c(1, 0, 0.1), 5)) : NaNs produced
+In pt(c(NA, 0, NaN, 1/0, -1/0), rep(c(1, 0, 0.1), 5)) : NaNs produced
 
 ##com.oracle.truffle.r.test.library.stats.TestStatFunctions.testFunctions22#Output.IgnoreWhitespace#
-#set.seed(1); qexp(rep(c(1, 0, 0.1), 5), c(NA, 0, NaN, 1/0, -1/0))
- [1]  NA   0 NaN NaN   0  NA Inf NaN   0 NaN  NA Inf NaN   0   0
+#set.seed(1); pt(rep(c(1, 0, 0.1), 5), c(NA, 0, NaN, 1/0, -1/0))
+ [1]        NA       NaN       NaN 0.8413447       NaN        NA       NaN
+ [8]       NaN 0.5398278       NaN        NA       NaN       NaN 0.5000000
+[15]       NaN
 Warning message:
-In qexp(rep(c(1, 0, 0.1), 5), c(NA, 0, NaN, 1/0, -1/0)) : NaNs produced
+In pt(rep(c(1, 0, 0.1), 5), c(NA, 0, NaN, 1/0, -1/0)) : NaNs produced
+
+##com.oracle.truffle.r.test.library.stats.TestStatFunctions.testFunctions22#Output.IgnoreWhitespace#
+#set.seed(1); qchisq(0, 10, lower.tail=FALSE, log.p=FALSE)
+[1] Inf
+
+##com.oracle.truffle.r.test.library.stats.TestStatFunctions.testFunctions22#Output.IgnoreWhitespace#
+#set.seed(1); qchisq(0, 10, lower.tail=FALSE, log.p=TRUE)
+[1] 0
+
+##com.oracle.truffle.r.test.library.stats.TestStatFunctions.testFunctions22#Output.IgnoreWhitespace#
+#set.seed(1); qchisq(0, 10, lower.tail=TRUE, log.p=FALSE)
+[1] 0
+
+##com.oracle.truffle.r.test.library.stats.TestStatFunctions.testFunctions22#Output.IgnoreWhitespace#
+#set.seed(1); qchisq(0, 10, lower.tail=TRUE, log.p=TRUE)
+[1] Inf
+
+##com.oracle.truffle.r.test.library.stats.TestStatFunctions.testFunctions22#Output.IgnoreWhitespace#
+#set.seed(1); qchisq(0, c(0.0653, 0.000123, 32e-80, 8833, 79e70, 0, -1), lower.tail=FALSE, log.p=FALSE)
+[1] Inf Inf Inf Inf Inf Inf Inf
+
+##com.oracle.truffle.r.test.library.stats.TestStatFunctions.testFunctions22#Output.IgnoreWhitespace#
+#set.seed(1); qchisq(0, c(0.0653, 0.000123, 32e-80, 8833, 79e70, 0, -1), lower.tail=FALSE, log.p=TRUE)
+[1] 0 0 0 0 0 0 0
+
+##com.oracle.truffle.r.test.library.stats.TestStatFunctions.testFunctions22#Output.IgnoreWhitespace#
+#set.seed(1); qchisq(0, c(0.0653, 0.000123, 32e-80, 8833, 79e70, 0, -1), lower.tail=TRUE, log.p=FALSE)
+[1] 0 0 0 0 0 0 0
+
+##com.oracle.truffle.r.test.library.stats.TestStatFunctions.testFunctions22#Output.IgnoreWhitespace#
+#set.seed(1); qchisq(0, c(0.0653, 0.000123, 32e-80, 8833, 79e70, 0, -1), lower.tail=TRUE, log.p=TRUE)
+[1] Inf Inf Inf Inf Inf Inf Inf
+
+##com.oracle.truffle.r.test.library.stats.TestStatFunctions.testFunctions22#Output.IgnoreWhitespace#
+#set.seed(1); qchisq(c(-1, 0, 0.2, 2), rep(c(-1, 0, 0.1, 0.9, 3), 4), lower.tail=FALSE, log.p=FALSE)
+ [1]      NaN      Inf 0.013564      NaN      NaN      Inf 0.000000      NaN
+ [9]      NaN      Inf      NaN      NaN      NaN      Inf 4.641628      NaN
+[17]      NaN      Inf 1.468957      NaN
+Warning message:
+In qchisq(c(-1, 0, 0.2, 2), rep(c(-1, 0, 0.1, 0.9, 3), 4), lower.tail = FALSE,  :
+  NaNs produced
+
+##com.oracle.truffle.r.test.library.stats.TestStatFunctions.testFunctions22#Output.IgnoreWhitespace#
+#set.seed(1); qchisq(c(-1, 0, 0.2, 2), rep(c(-1, 0, 0.1, 0.9, 3), 4), lower.tail=FALSE, log.p=TRUE)
+ [1]         NaN 0.000000000         NaN         NaN 3.158142952 0.000000000
+ [7]         NaN         NaN 0.691572992 0.000000000         NaN         NaN
+[13] 0.000121286 0.000000000         NaN         NaN 0.000000000 0.000000000
+[19]         NaN         NaN
+Warning message:
+In qchisq(c(-1, 0, 0.2, 2), rep(c(-1, 0, 0.1, 0.9, 3), 4), lower.tail = FALSE,  :
+  NaNs produced
+
+##com.oracle.truffle.r.test.library.stats.TestStatFunctions.testFunctions22#Output.IgnoreWhitespace#
+#set.seed(1); qchisq(c(-1, 0, 0.2, 2), rep(c(-1, 0, 0.1, 0.9, 3), 4), lower.tail=TRUE, log.p=FALSE)
+ [1]          NaN 0.000000e+00 1.225708e-14          NaN          NaN
+ [6] 0.000000e+00 0.000000e+00          NaN          NaN 0.000000e+00
+[11]          NaN          NaN          NaN 0.000000e+00 1.005174e+00
+[16]          NaN          NaN 0.000000e+00 4.335644e-02          NaN
+Warning message:
+In qchisq(c(-1, 0, 0.2, 2), rep(c(-1, 0, 0.1, 0.9, 3), 4), lower.tail = TRUE,  :
+  NaNs produced
+
+##com.oracle.truffle.r.test.library.stats.TestStatFunctions.testFunctions22#Output.IgnoreWhitespace#
+#set.seed(1); qchisq(c(-1, 0, 0.2, 2), rep(c(-1, 0, 0.1, 0.9, 3), 4), lower.tail=TRUE, log.p=TRUE)
+ [1]          NaN          Inf          NaN          NaN 1.721698e+00
+ [6]          Inf          NaN          NaN 1.756852e-01          Inf
+[11]          NaN          NaN 2.409337e-09          Inf          NaN
+[16]          NaN 0.000000e+00          Inf          NaN          NaN
+Warning message:
+In qchisq(c(-1, 0, 0.2, 2), rep(c(-1, 0, 0.1, 0.9, 3), 4), lower.tail = TRUE,  :
+  NaNs produced
+
+##com.oracle.truffle.r.test.library.stats.TestStatFunctions.testFunctions22#Output.IgnoreWhitespace#
+#set.seed(1); qchisq(c(NA, 0, NaN, 1/0, -1/0), rep(c(1, 0, 0.1), 5))
+ [1]  NA   0 NaN NaN NaN  NA   0 NaN NaN NaN  NA   0 NaN NaN NaN
+Warning message:
+In qchisq(c(NA, 0, NaN, 1/0, -1/0), rep(c(1, 0, 0.1), 5)) : NaNs produced
+
+##com.oracle.truffle.r.test.library.stats.TestStatFunctions.testFunctions22#Output.IgnoreWhitespace#
+#set.seed(1); qchisq(rep(c(1, 0, 0.1), 5), c(NA, 0, NaN, 1/0, -1/0))
+ [1]  NA   0 NaN Inf   0  NA Inf NaN Inf Inf  NA   0 NaN   0 NaN
+Warning messages:
+1: In qchisq(rep(c(1, 0, 0.1), 5), c(NA, 0, NaN, 1/0, -1/0)) :
+  value out of range in 'lgamma'
+2: In qchisq(rep(c(1, 0, 0.1), 5), c(NA, 0, NaN, 1/0, -1/0)) :
+  NaNs produced
 
 ##com.oracle.truffle.r.test.library.stats.TestStatFunctions.testFunctions22#Output.IgnoreWhitespace#
 #set.seed(1); qgeom(0, 10, lower.tail=FALSE, log.p=FALSE)
@@ -114864,635 +118792,709 @@ In qgeom(c(NA, 0, NaN, 1/0, -1/0), rep(c(1, 0, 0.1), 5)) : NaNs produced
 Warning message:
 In qgeom(rep(c(1, 0, 0.1), 5), c(NA, 0, NaN, 1/0, -1/0)) : NaNs produced
 
-##com.oracle.truffle.r.test.library.stats.TestStatFunctions.testFunctions31#Output.IgnoreWhitespace#
-#set.seed(1); dbeta(0, c(0.0653, 0.000123, 32e-80, 8833, 79e70), c(0.0653, 0.000123, 32e-80, 8833, 79e70, 0, -1), log=FALSE)
-[1] Inf Inf Inf   0   0   0 NaN
+##com.oracle.truffle.r.test.library.stats.TestStatFunctions.testFunctions22#Output.IgnoreWhitespace#
+#set.seed(1); qpois(0, 10, lower.tail=FALSE, log.p=FALSE)
+[1] Inf
+
+##com.oracle.truffle.r.test.library.stats.TestStatFunctions.testFunctions22#Output.IgnoreWhitespace#
+#set.seed(1); qpois(0, 10, lower.tail=FALSE, log.p=TRUE)
+[1] 0
+
+##com.oracle.truffle.r.test.library.stats.TestStatFunctions.testFunctions22#Output.IgnoreWhitespace#
+#set.seed(1); qpois(0, 10, lower.tail=TRUE, log.p=FALSE)
+[1] 0
+
+##com.oracle.truffle.r.test.library.stats.TestStatFunctions.testFunctions22#Output.IgnoreWhitespace#
+#set.seed(1); qpois(0, 10, lower.tail=TRUE, log.p=TRUE)
+[1] Inf
+
+##com.oracle.truffle.r.test.library.stats.TestStatFunctions.testFunctions22#Output.IgnoreWhitespace#
+#set.seed(1); qpois(0, c(0.0653, 0.000123, 32e-80, 8833, 79e70, 0, -1), lower.tail=FALSE, log.p=FALSE)
+[1] Inf Inf Inf Inf Inf   0 NaN
+Warning message:
+In qpois(0, c(0.0653, 0.000123, 3.2e-79, 8833, 7.9e+71, 0, -1),  :
+  NaNs produced
+
+##com.oracle.truffle.r.test.library.stats.TestStatFunctions.testFunctions22#Output.IgnoreWhitespace#
+#set.seed(1); qpois(0, c(0.0653, 0.000123, 32e-80, 8833, 79e70, 0, -1), lower.tail=FALSE, log.p=TRUE)
+[1]   0   0   0   0   0   0 NaN
+Warning message:
+In qpois(0, c(0.0653, 0.000123, 3.2e-79, 8833, 7.9e+71, 0, -1),  :
+  NaNs produced
+
+##com.oracle.truffle.r.test.library.stats.TestStatFunctions.testFunctions22#Output.IgnoreWhitespace#
+#set.seed(1); qpois(0, c(0.0653, 0.000123, 32e-80, 8833, 79e70, 0, -1), lower.tail=TRUE, log.p=FALSE)
+[1]   0   0   0   0   0   0 NaN
+Warning message:
+In qpois(0, c(0.0653, 0.000123, 3.2e-79, 8833, 7.9e+71, 0, -1),  :
+  NaNs produced
+
+##com.oracle.truffle.r.test.library.stats.TestStatFunctions.testFunctions22#Output.IgnoreWhitespace#
+#set.seed(1); qpois(0, c(0.0653, 0.000123, 32e-80, 8833, 79e70, 0, -1), lower.tail=TRUE, log.p=TRUE)
+[1] Inf Inf Inf Inf Inf   0 NaN
 Warning message:
-In dbeta(0, c(0.0653, 0.000123, 3.2e-79, 8833, 7.9e+71), c(0.0653,  :
+In qpois(0, c(0.0653, 0.000123, 3.2e-79, 8833, 7.9e+71, 0, -1),  :
   NaNs produced
 
+##com.oracle.truffle.r.test.library.stats.TestStatFunctions.testFunctions22#Output.IgnoreWhitespace#
+#set.seed(1); qpois(c(-1, 0, 0.2, 2), rep(c(-1, 0, 0.1, 0.9, 3), 4), lower.tail=FALSE, log.p=FALSE)
+ [1] NaN   0   0 NaN NaN NaN   0 NaN NaN Inf NaN   0 NaN Inf   4 NaN   0 Inf   2
+[20] NaN
+Warning message:
+In qpois(c(-1, 0, 0.2, 2), rep(c(-1, 0, 0.1, 0.9, 3), 4), lower.tail = FALSE,  :
+  NaNs produced
+
+##com.oracle.truffle.r.test.library.stats.TestStatFunctions.testFunctions22#Output.IgnoreWhitespace#
+#set.seed(1); qpois(c(-1, 0, 0.2, 2), rep(c(-1, 0, 0.1, 0.9, 3), 4), lower.tail=FALSE, log.p=TRUE)
+ [1] NaN   0 NaN NaN   3 NaN   0 NaN   1   0 NaN   0   0   0 NaN NaN   0   0 NaN
+[20] NaN
+Warning message:
+In qpois(c(-1, 0, 0.2, 2), rep(c(-1, 0, 0.1, 0.9, 3), 4), lower.tail = FALSE,  :
+  NaNs produced
+
+##com.oracle.truffle.r.test.library.stats.TestStatFunctions.testFunctions22#Output.IgnoreWhitespace#
+#set.seed(1); qpois(c(-1, 0, 0.2, 2), rep(c(-1, 0, 0.1, 0.9, 3), 4), lower.tail=TRUE, log.p=FALSE)
+ [1] NaN   0   0 NaN NaN NaN   0 NaN NaN   0 NaN   0 NaN   0   2 NaN   0   0   0
+[20] NaN
+Warning message:
+In qpois(c(-1, 0, 0.2, 2), rep(c(-1, 0, 0.1, 0.9, 3), 4), lower.tail = TRUE,  :
+  NaNs produced
+
+##com.oracle.truffle.r.test.library.stats.TestStatFunctions.testFunctions22#Output.IgnoreWhitespace#
+#set.seed(1); qpois(c(-1, 0, 0.2, 2), rep(c(-1, 0, 0.1, 0.9, 3), 4), lower.tail=TRUE, log.p=TRUE)
+ [1] NaN   0 NaN NaN   2 NaN   0 NaN   0 Inf NaN   0   0 Inf NaN NaN   0 Inf NaN
+[20] NaN
+Warning message:
+In qpois(c(-1, 0, 0.2, 2), rep(c(-1, 0, 0.1, 0.9, 3), 4), lower.tail = TRUE,  :
+  NaNs produced
+
+##com.oracle.truffle.r.test.library.stats.TestStatFunctions.testFunctions22#Output.IgnoreWhitespace#
+#set.seed(1); qpois(c(NA, 0, NaN, 1/0, -1/0), rep(c(1, 0, 0.1), 5))
+ [1]  NA   0 NaN NaN   0  NA   0 NaN NaN NaN  NA   0 NaN   0 NaN
+Warning message:
+In qpois(c(NA, 0, NaN, 1/0, -1/0), rep(c(1, 0, 0.1), 5)) : NaNs produced
+
+##com.oracle.truffle.r.test.library.stats.TestStatFunctions.testFunctions22#Output.IgnoreWhitespace#
+#set.seed(1); qpois(rep(c(1, 0, 0.1), 5), c(NA, 0, NaN, 1/0, -1/0))
+ [1]  NA   0 NaN NaN NaN  NA   0 NaN NaN NaN  NA   0 NaN NaN NaN
+Warning message:
+In qpois(rep(c(1, 0, 0.1), 5), c(NA, 0, NaN, 1/0, -1/0)) : NaNs produced
+
+##com.oracle.truffle.r.test.library.stats.TestStatFunctions.testFunctions22#Output.IgnoreWhitespace#
+#set.seed(1); qt(0, 10, lower.tail=FALSE, log.p=FALSE)
+[1] Inf
+
+##com.oracle.truffle.r.test.library.stats.TestStatFunctions.testFunctions22#Output.IgnoreWhitespace#
+#set.seed(1); qt(0, 10, lower.tail=FALSE, log.p=TRUE)
+[1] -Inf
+
+##com.oracle.truffle.r.test.library.stats.TestStatFunctions.testFunctions22#Output.IgnoreWhitespace#
+#set.seed(1); qt(0, 10, lower.tail=TRUE, log.p=FALSE)
+[1] -Inf
+
+##com.oracle.truffle.r.test.library.stats.TestStatFunctions.testFunctions22#Output.IgnoreWhitespace#
+#set.seed(1); qt(0, 10, lower.tail=TRUE, log.p=TRUE)
+[1] Inf
+
+##com.oracle.truffle.r.test.library.stats.TestStatFunctions.testFunctions22#Output.IgnoreWhitespace#
+#set.seed(1); qt(0, c(0.0653, 0.000123, 32e-80, 8833, 79e70, 0, -1), lower.tail=FALSE, log.p=FALSE)
+[1] Inf Inf Inf Inf Inf Inf Inf
+
+##com.oracle.truffle.r.test.library.stats.TestStatFunctions.testFunctions22#Output.IgnoreWhitespace#
+#set.seed(1); qt(0, c(0.0653, 0.000123, 32e-80, 8833, 79e70, 0, -1), lower.tail=FALSE, log.p=TRUE)
+[1] -Inf -Inf -Inf -Inf -Inf -Inf -Inf
+
+##com.oracle.truffle.r.test.library.stats.TestStatFunctions.testFunctions22#Output.IgnoreWhitespace#
+#set.seed(1); qt(0, c(0.0653, 0.000123, 32e-80, 8833, 79e70, 0, -1), lower.tail=TRUE, log.p=FALSE)
+[1] -Inf -Inf -Inf -Inf -Inf -Inf -Inf
+
+##com.oracle.truffle.r.test.library.stats.TestStatFunctions.testFunctions22#Output.IgnoreWhitespace#
+#set.seed(1); qt(0, c(0.0653, 0.000123, 32e-80, 8833, 79e70, 0, -1), lower.tail=TRUE, log.p=TRUE)
+[1] Inf Inf Inf Inf Inf Inf Inf
+
+##com.oracle.truffle.r.test.library.stats.TestStatFunctions.testFunctions22#Output.IgnoreWhitespace#
+#set.seed(1); qt(c(-1, 0, 0.2, 2), rep(c(-1, 0, 0.1, 0.9, 3), 4), lower.tail=FALSE, log.p=FALSE)
+ [1]          NaN          Inf 1566.8219615          NaN          NaN
+ [6]          Inf          NaN          NaN          NaN          Inf
+[11]          NaN          NaN          NaN          Inf    0.9784723
+[16]          NaN          NaN          Inf    1.4638968          NaN
+Warning message:
+In qt(c(-1, 0, 0.2, 2), rep(c(-1, 0, 0.1, 0.9, 3), 4), lower.tail = FALSE,  :
+  NaNs produced
+
+##com.oracle.truffle.r.test.library.stats.TestStatFunctions.testFunctions22#Output.IgnoreWhitespace#
+#set.seed(1); qt(c(-1, 0, 0.2, 2), rep(c(-1, 0, 0.1, 0.9, 3), 4), lower.tail=FALSE, log.p=TRUE)
+ [1]       NaN      -Inf       NaN       NaN 0.3702990      -Inf       NaN
+ [8]       NaN 0.4528167      -Inf       NaN       NaN 3.5265712      -Inf
+[15]       NaN       NaN       NaN      -Inf       NaN       NaN
+Warning message:
+In qt(c(-1, 0, 0.2, 2), rep(c(-1, 0, 0.1, 0.9, 3), 4), lower.tail = FALSE,  :
+  NaNs produced
+
+##com.oracle.truffle.r.test.library.stats.TestStatFunctions.testFunctions22#Output.IgnoreWhitespace#
+#set.seed(1); qt(c(-1, 0, 0.2, 2), rep(c(-1, 0, 0.1, 0.9, 3), 4), lower.tail=TRUE, log.p=FALSE)
+ [1]           NaN          -Inf -1566.8219615           NaN           NaN
+ [6]          -Inf           NaN           NaN           NaN          -Inf
+[11]           NaN           NaN           NaN          -Inf    -0.9784723
+[16]           NaN           NaN          -Inf    -1.4638968           NaN
+Warning message:
+In qt(c(-1, 0, 0.2, 2), rep(c(-1, 0, 0.1, 0.9, 3), 4), lower.tail = TRUE,  :
+  NaNs produced
+
+##com.oracle.truffle.r.test.library.stats.TestStatFunctions.testFunctions22#Output.IgnoreWhitespace#
+#set.seed(1); qt(c(-1, 0, 0.2, 2), rep(c(-1, 0, 0.1, 0.9, 3), 4), lower.tail=TRUE, log.p=TRUE)
+ [1]        NaN        Inf        NaN        NaN -0.3702990        Inf
+ [7]        NaN        NaN -0.4528167        Inf        NaN        NaN
+[13] -3.5265712        Inf        NaN        NaN        NaN        Inf
+[19]        NaN        NaN
+Warning message:
+In qt(c(-1, 0, 0.2, 2), rep(c(-1, 0, 0.1, 0.9, 3), 4), lower.tail = TRUE,  :
+  NaNs produced
+
+##com.oracle.truffle.r.test.library.stats.TestStatFunctions.testFunctions22#Output.IgnoreWhitespace#
+#set.seed(1); qt(c(NA, 0, NaN, 1/0, -1/0), rep(c(1, 0, 0.1), 5))
+ [1]   NA -Inf  NaN  NaN  NaN   NA -Inf  NaN  NaN  NaN   NA -Inf  NaN  NaN  NaN
+Warning message:
+In qt(c(NA, 0, NaN, 1/0, -1/0), rep(c(1, 0, 0.1), 5)) : NaNs produced
+
+##com.oracle.truffle.r.test.library.stats.TestStatFunctions.testFunctions22#Output.IgnoreWhitespace#
+#set.seed(1); qt(rep(c(1, 0, 0.1), 5), c(NA, 0, NaN, 1/0, -1/0))
+ [1]        NA      -Inf       NaN       Inf      -Inf        NA       Inf
+ [8]       NaN -1.281552       Inf        NA       NaN       NaN      -Inf
+[15]       NaN
+Warning message:
+In qt(rep(c(1, 0, 0.1), 5), c(NA, 0, NaN, 1/0, -1/0)) : NaNs produced
+
 ##com.oracle.truffle.r.test.library.stats.TestStatFunctions.testFunctions31#Output.IgnoreWhitespace#
-#set.seed(1); dbeta(0, c(NA, 0, NaN, 1/0, -1/0), c(NaN, NaN, NA, 0, 1/0, -1/0), log=FALSE)
-[1]  NA NaN  NA   0 NaN  NA
+#set.seed(1); dlnorm(0, c(0.0653, 0.000123, 32e-80, 8833, 79e70), c(0.0653, 0.000123, 32e-80, 8833, 79e70, 0, -1), log=FALSE)
+[1]   0   0   0   0   0   0 NaN
 Warning message:
-In dbeta(0, c(NA, 0, NaN, 1/0, -1/0), c(NaN, NaN, NA, 0, 1/0, -1/0),  :
+In dlnorm(0, c(0.0653, 0.000123, 3.2e-79, 8833, 7.9e+71), c(0.0653,  :
   NaNs produced
 
 ##com.oracle.truffle.r.test.library.stats.TestStatFunctions.testFunctions31#Output.IgnoreWhitespace#
-#set.seed(1); dbeta(10, 10, 10, log=TRUE)
-[1] -Inf
+#set.seed(1); dlnorm(0, c(NA, 0, NaN, 1/0, -1/0), c(NaN, NaN, NA, 0, 1/0, -1/0), log=FALSE)
+[1]  NA NaN  NA   0   0  NA
 
 ##com.oracle.truffle.r.test.library.stats.TestStatFunctions.testFunctions31#Output.IgnoreWhitespace#
-#set.seed(1); dbeta(3, 3, 3, log=FALSE)
-[1] 0
+#set.seed(1); dlnorm(10, 10, 10, log=TRUE)
+[1] -5.82036
 
 ##com.oracle.truffle.r.test.library.stats.TestStatFunctions.testFunctions31#Output.IgnoreWhitespace#
-#set.seed(1); dbeta(c(-1, 0, 1), c(-1, 0, 0.2, 2:5), rep(c(-1, 0, 0.1, 0.9, 3), 12), log=FALSE)
- [1] NaN Inf Inf   0   0 NaN   0 NaN   0   0 NaN Inf   0   0 NaN NaN   0 Inf   0
-[20]   0 NaN NaN Inf Inf   0 NaN Inf   0 NaN   0 NaN   0 Inf   0   0 NaN   0 Inf
-[39] Inf   0 NaN Inf NaN Inf   0 NaN   0 Inf   0 NaN NaN   0   0 Inf   0 NaN NaN
-[58]   0 Inf   0
+#set.seed(1); dlnorm(3, 3, 3, log=FALSE)
+[1] 0.03626103
+
+##com.oracle.truffle.r.test.library.stats.TestStatFunctions.testFunctions31#Output.IgnoreWhitespace#
+#set.seed(1); dlnorm(c(-1, 0, 1), c(-1, 0, 0.2, 2:5), rep(c(-1, 0, 0.1, 0.9, 3), 12), log=FALSE)
+ [1]           NaN  0.000000e+00  5.399097e-01  0.000000e+00  0.000000e+00
+ [6]           NaN  0.000000e+00  0.000000e+00  4.432692e-01  0.000000e+00
+[11]           NaN  0.000000e+00  0.000000e+00  0.000000e+00  1.257944e-01
+[16]           NaN  0.000000e+00  5.520948e-87  0.000000e+00  0.000000e+00
+[21]           NaN  0.000000e+00  0.000000e+00  4.324583e-01  0.000000e+00
+[26]           NaN  0.000000e+00  0.000000e+00  0.000000e+00  1.329808e-01
+[31]           NaN  0.000000e+00 1.473646e-195  0.000000e+00  0.000000e+00
+[36]           NaN  0.000000e+00  0.000000e+00  3.752628e-02  0.000000e+00
+[41]           NaN  0.000000e+00  0.000000e+00  0.000000e+00  1.326856e-01
+[46]           NaN  0.000000e+00  0.000000e+00  0.000000e+00  0.000000e+00
+[51]           NaN  0.000000e+00  0.000000e+00  1.713643e-03  0.000000e+00
+[56]           NaN  0.000000e+00  0.000000e+00  0.000000e+00  1.064827e-01
 Warning message:
-In dbeta(c(-1, 0, 1), c(-1, 0, 0.2, 2:5), rep(c(-1, 0, 0.1, 0.9,  :
+In dlnorm(c(-1, 0, 1), c(-1, 0, 0.2, 2:5), rep(c(-1, 0, 0.1, 0.9,  :
   NaNs produced
 
 ##com.oracle.truffle.r.test.library.stats.TestStatFunctions.testFunctions31#Output.IgnoreWhitespace#
-#set.seed(1); dbeta(c(-1, 0, 1), c(-1, 0, 0.2, 2:5), rep(c(-1, 0, 0.1, 0.9, 3), 12), log=TRUE)
- [1]  NaN  Inf  Inf -Inf -Inf  NaN -Inf  NaN -Inf -Inf  NaN  Inf -Inf -Inf  NaN
-[16]  NaN -Inf  Inf -Inf -Inf  NaN  NaN  Inf  Inf -Inf  NaN  Inf -Inf  NaN -Inf
-[31]  NaN -Inf  Inf -Inf -Inf  NaN -Inf  Inf  Inf -Inf  NaN  Inf  NaN  Inf -Inf
-[46]  NaN -Inf  Inf -Inf  NaN  NaN -Inf -Inf  Inf -Inf  NaN  NaN -Inf  Inf -Inf
+#set.seed(1); dlnorm(c(-1, 0, 1), c(-1, 0, 0.2, 2:5), rep(c(-1, 0, 0.1, 0.9, 3), 12), log=TRUE)
+ [1]          NaN         -Inf   -0.6163534         -Inf         -Inf
+ [6]          NaN         -Inf         -Inf   -0.8135780         -Inf
+[11]          NaN         -Inf         -Inf         -Inf   -2.0731064
+[16]          NaN         -Inf -198.6163534         -Inf         -Inf
+[21]          NaN         -Inf         -Inf   -0.8382694         -Inf
+[26]          NaN         -Inf         -Inf         -Inf   -2.0175508
+[31]          NaN         -Inf -448.6163534         -Inf         -Inf
+[36]          NaN         -Inf         -Inf   -3.2827138         -Inf
+[41]          NaN         -Inf         -Inf         -Inf   -2.0197730
+[46]          NaN         -Inf -798.6163534         -Inf         -Inf
+[51]          NaN         -Inf         -Inf   -6.3691336         -Inf
+[56]          NaN         -Inf         -Inf         -Inf   -2.2397730
 Warning message:
-In dbeta(c(-1, 0, 1), c(-1, 0, 0.2, 2:5), rep(c(-1, 0, 0.1, 0.9,  :
+In dlnorm(c(-1, 0, 1), c(-1, 0, 0.2, 2:5), rep(c(-1, 0, 0.1, 0.9,  :
   NaNs produced
 
 ##com.oracle.truffle.r.test.library.stats.TestStatFunctions.testFunctions31#Output.IgnoreWhitespace#
-#set.seed(1); dbeta(c(NA, NaN, 1/0, -1/0), 2, 2, log=FALSE)
+#set.seed(1); dlnorm(c(NA, NaN, 1/0, -1/0), 2, 2, log=FALSE)
 [1]  NA NaN   0   0
 
 ##com.oracle.truffle.r.test.library.stats.TestStatFunctions.testFunctions31#Output.IgnoreWhitespace#
-#set.seed(1); dcauchy(0, c(0.0653, 0.000123, 32e-80, 8833, 79e70), c(0.0653, 0.000123, 32e-80, 8833, 79e70, 0, -1), log=FALSE)
-[1] 2.437289e+00 1.293943e+03 4.973592e+77 1.801822e-05 2.014620e-73
+#set.seed(1); dlogis(0, c(0.0653, 0.000123, 32e-80, 8833, 79e70), c(0.0653, 0.000123, 32e-80, 8833, 79e70, 0, -1), log=FALSE)
+[1] 3.010902e+00 1.598471e+03 6.144123e+77 2.225879e-05 2.488759e-73
 [6]          NaN          NaN
 Warning message:
-In dcauchy(0, c(0.0653, 0.000123, 3.2e-79, 8833, 7.9e+71), c(0.0653,  :
+In dlogis(0, c(0.0653, 0.000123, 3.2e-79, 8833, 7.9e+71), c(0.0653,  :
   NaNs produced
 
 ##com.oracle.truffle.r.test.library.stats.TestStatFunctions.testFunctions31#Output.IgnoreWhitespace#
-#set.seed(1); dcauchy(0, c(NA, 0, NaN, 1/0, -1/0), c(NaN, NaN, NA, 0, 1/0, -1/0), log=FALSE)
+#set.seed(1); dlogis(0, c(NA, 0, NaN, 1/0, -1/0), c(NaN, NaN, NA, 0, 1/0, -1/0), log=FALSE)
 [1]  NA NaN  NA NaN NaN  NA
 Warning message:
-In dcauchy(0, c(NA, 0, NaN, 1/0, -1/0), c(NaN, NaN, NA, 0, 1/0,  :
+In dlogis(0, c(NA, 0, NaN, 1/0, -1/0), c(NaN, NaN, NA, 0, 1/0, -1/0),  :
   NaNs produced
 
 ##com.oracle.truffle.r.test.library.stats.TestStatFunctions.testFunctions31#Output.IgnoreWhitespace#
-#set.seed(1); dcauchy(10, 10, 10, log=TRUE)
-[1] -3.447315
+#set.seed(1); dlogis(10, 10, 10, log=TRUE)
+[1] -3.688879
 
 ##com.oracle.truffle.r.test.library.stats.TestStatFunctions.testFunctions31#Output.IgnoreWhitespace#
-#set.seed(1); dcauchy(3, 3, 3, log=FALSE)
-[1] 0.1061033
+#set.seed(1); dlogis(3, 3, 3, log=FALSE)
+[1] 0.08333333
 
 ##com.oracle.truffle.r.test.library.stats.TestStatFunctions.testFunctions31#Output.IgnoreWhitespace#
-#set.seed(1); dcauchy(c(-1, 0, 1), c(-1, 0, 0.2, 2:5), rep(c(-1, 0, 0.1, 0.9, 3), 12), log=FALSE)
- [1]          NaN          NaN 0.0489707517 0.0292027419 0.0530516477
- [6]          NaN          NaN 0.0315158303 0.1582756340 0.0914683581
-[11]          NaN          NaN 0.0012727305 0.0110995311 0.0734561276
-[16]          NaN          NaN 0.0315158303 0.0170421712 0.0381971863
-[21]          NaN          NaN 3.1830988618 0.1975716535 0.0530516477
-[26]          NaN          NaN 0.0008839486 0.1582756340 0.0954929659
-[31]          NaN          NaN 0.0079379024 0.0110995311 0.0280861664
-[36]          NaN          NaN 0.6366197724 0.1582756340 0.0381971863
-[41]          NaN          NaN 3.1830988618 0.3536776513 0.0990590932
-[46]          NaN          NaN 0.0035328511 0.0077826378 0.0954929659
-[51]          NaN          NaN 0.0079379024 0.0595590224 0.0280861664
-[56]          NaN          NaN 0.0315158303 0.3370339971 0.0954929659
-Warning message:
-In dcauchy(c(-1, 0, 1), c(-1, 0, 0.2, 2:5), rep(c(-1, 0, 0.1, 0.9,  :
+#set.seed(1); dlogis(c(-1, 0, 1), c(-1, 0, 0.2, 2:5), rep(c(-1, 0, 0.1, 0.9, 3), 12), log=FALSE)
+ [1]          NaN          NaN 3.352377e-03 3.695414e-02 6.553731e-02
+ [6]          NaN          NaN 4.539581e-04 2.070294e-01 8.008692e-02
+[11]          NaN          NaN 1.928750e-21 4.262447e-03 7.471913e-02
+[16]          NaN          NaN 4.539581e-04 1.274732e-02 5.503034e-02
+[21]          NaN          NaN 2.500000e+00 2.294007e-01 6.553731e-02
+[26]          NaN          NaN 8.756511e-26 2.070294e-01 8.106072e-02
+[31]          NaN          NaN 2.061154e-08 4.262447e-03 4.454324e-02
+[36]          NaN          NaN 1.049936e+00 2.070294e-01 5.503034e-02
+[41]          NaN          NaN 2.500000e+00 2.777778e-01 8.186923e-02
+[46]          NaN          NaN 9.357623e-13 1.410445e-03 8.106072e-02
+[51]          NaN          NaN 2.061154e-08 9.801458e-02 4.454324e-02
+[56]          NaN          NaN 4.539581e-04 2.743765e-01 8.106072e-02
+Warning message:
+In dlogis(c(-1, 0, 1), c(-1, 0, 0.2, 2:5), rep(c(-1, 0, 0.1, 0.9,  :
   NaNs produced
 
 ##com.oracle.truffle.r.test.library.stats.TestStatFunctions.testFunctions31#Output.IgnoreWhitespace#
-#set.seed(1); dcauchy(c(-1, 0, 1), c(-1, 0, 0.2, 2:5), rep(c(-1, 0, 0.1, 0.9, 3), 12), log=TRUE)
- [1]        NaN        NaN -3.0165321 -3.5334927 -2.9364894        NaN
- [7]        NaN -3.4572653 -1.8434172 -2.3917622        NaN        NaN
-[13] -6.6665907 -4.5008524 -2.6110670        NaN        NaN -3.4572653
-[19] -4.0720643 -3.2649934        NaN        NaN  1.1578552 -1.6216540
-[25] -2.9364894        NaN        NaN -7.0311117 -1.8434172 -2.3487027
-[31]        NaN        NaN -4.8361062 -4.5008524 -3.5724781        NaN
-[37]        NaN -0.4515827 -1.8434172 -3.2649934        NaN        NaN
-[43]  1.1578552 -1.0393694 -2.3120387        NaN        NaN -5.6456501
-[49] -4.8558599 -2.3487027        NaN        NaN -4.8361062 -2.8207875
-[55] -3.5724781        NaN        NaN -3.4572653 -1.0875715 -2.3487027
-Warning message:
-In dcauchy(c(-1, 0, 1), c(-1, 0, 0.2, 2:5), rep(c(-1, 0, 0.1, 0.9,  :
+#set.seed(1); dlogis(c(-1, 0, 1), c(-1, 0, 0.2, 2:5), rep(c(-1, 0, 0.1, 0.9, 3), 12), log=TRUE)
+ [1]          NaN          NaN  -5.69808572  -3.29807765  -2.72513566
+ [6]          NaN          NaN  -7.69750570  -1.57489456  -2.52464279
+[11]          NaN          NaN -47.69741491  -5.45791197  -2.59401913
+[16]          NaN          NaN  -7.69750570  -4.36243434  -2.89987067
+[21]          NaN          NaN   0.91629073  -1.47228488  -2.72513566
+[26]          NaN          NaN -57.69741491  -1.57489456  -2.51255677
+[31]          NaN          NaN -17.69741491  -5.45791197  -3.11129493
+[36]          NaN          NaN   0.04872907  -1.57489456  -2.89987067
+[41]          NaN          NaN   0.91629073  -1.28093385  -2.50263200
+[46]          NaN          NaN -27.69741491  -6.56384980  -2.51255677
+[51]          NaN          NaN -17.69741491  -2.32263907  -3.11129493
+[56]          NaN          NaN  -7.69750570  -1.29325421  -2.51255677
+Warning message:
+In dlogis(c(-1, 0, 1), c(-1, 0, 0.2, 2:5), rep(c(-1, 0, 0.1, 0.9,  :
   NaNs produced
 
 ##com.oracle.truffle.r.test.library.stats.TestStatFunctions.testFunctions31#Output.IgnoreWhitespace#
-#set.seed(1); dcauchy(c(NA, NaN, 1/0, -1/0), 2, 2, log=FALSE)
+#set.seed(1); dlogis(c(NA, NaN, 1/0, -1/0), 2, 2, log=FALSE)
 [1]  NA NaN   0   0
 
-##com.oracle.truffle.r.test.library.stats.TestStatFunctions.testFunctions31#Output.IgnoreWhitespace#
-#set.seed(1); dgamma(0, c(0.0653, 0.000123, 32e-80, 8833, 79e70), c(0.0653, 0.000123, 32e-80, 8833, 79e70, 0, -1), log=FALSE)
-[1] Inf Inf Inf   0   0 Inf NaN
+##com.oracle.truffle.r.test.library.stats.TestStatFunctions.testFunctions32#Output.MayIgnoreWarningContext#
+#set.seed(1); pbinom(0, 10, 10, lower.tail=FALSE, log.p=FALSE)
+[1] NaN
 Warning message:
-In dgamma(0, c(0.0653, 0.000123, 3.2e-79, 8833, 7.9e+71), c(0.0653,  :
-  NaNs produced
+In pbinom(0, 10, 10, lower.tail = FALSE, log.p = FALSE) : NaNs produced
 
-##com.oracle.truffle.r.test.library.stats.TestStatFunctions.testFunctions31#Output.IgnoreWhitespace#
-#set.seed(1); dgamma(0, c(NA, 0, NaN, 1/0, -1/0), c(NaN, NaN, NA, 0, 1/0, -1/0), log=FALSE)
-[1]  NA NaN  NA   0 NaN  NA
+##com.oracle.truffle.r.test.library.stats.TestStatFunctions.testFunctions32#Output.MayIgnoreWarningContext#
+#set.seed(1); pbinom(0, 10, 10, lower.tail=FALSE, log.p=TRUE)
+[1] NaN
 Warning message:
-In dgamma(0, c(NA, 0, NaN, 1/0, -1/0), c(NaN, NaN, NA, 0, 1/0, -1/0),  :
-  NaNs produced
-
-##com.oracle.truffle.r.test.library.stats.TestStatFunctions.testFunctions31#Output.IgnoreWhitespace#
-#set.seed(1); dgamma(10, 10, 10, log=TRUE)
-[1] -69.05271
-
-##com.oracle.truffle.r.test.library.stats.TestStatFunctions.testFunctions31#Output.IgnoreWhitespace#
-#set.seed(1); dgamma(3, 3, 3, log=FALSE)
-[1] 0.01499429
-
-##com.oracle.truffle.r.test.library.stats.TestStatFunctions.testFunctions31#Output.IgnoreWhitespace#
-#set.seed(1); dgamma(c(-1, 0, 1), c(-1, 0, 0.2, 2:5), rep(c(-1, 0, 0.1, 0.9, 3), 12), log=FALSE)
- [1]          NaN          Inf 1.243592e-01 0.000000e+00 0.000000e+00
- [6]          NaN 0.000000e+00          NaN 0.000000e+00 0.000000e+00
-[11]          NaN 0.000000e+00 0.000000e+00 0.000000e+00          NaN
-[16]          NaN          Inf 9.048374e-03 0.000000e+00 0.000000e+00
-[21]          NaN          NaN          Inf 8.671435e-02 0.000000e+00
-[26]          NaN 0.000000e+00 0.000000e+00          NaN 0.000000e+00
-[31]          NaN 0.000000e+00 4.524187e-04 0.000000e+00 0.000000e+00
-[36]          NaN 0.000000e+00          Inf 3.293214e-01 0.000000e+00
-[41]          NaN 0.000000e+00          NaN          Inf 1.350978e-02
-[46]          NaN 0.000000e+00 1.508062e-05 0.000000e+00          NaN
-[51]          NaN 0.000000e+00 0.000000e+00 1.481946e-01 0.000000e+00
-[56]          NaN          NaN 0.000000e+00          Inf 4.480836e-01
-Warning message:
-In dgamma(c(-1, 0, 1), c(-1, 0, 0.2, 2:5), rep(c(-1, 0, 0.1, 0.9,  :
-  NaNs produced
-
-##com.oracle.truffle.r.test.library.stats.TestStatFunctions.testFunctions31#Output.IgnoreWhitespace#
-#set.seed(1); dgamma(c(-1, 0, 1), c(-1, 0, 0.2, 2:5), rep(c(-1, 0, 0.1, 0.9, 3), 12), log=TRUE)
- [1]         NaN         Inf  -2.0845808        -Inf        -Inf         NaN
- [7]        -Inf         NaN        -Inf        -Inf         NaN        -Inf
-[13]        -Inf        -Inf         NaN         NaN         Inf  -4.7051702
-[19]        -Inf        -Inf         NaN         NaN         Inf  -2.4451359
-[25]        -Inf         NaN        -Inf        -Inf         NaN        -Inf
-[31]         NaN        -Inf  -7.7009025        -Inf        -Inf         NaN
-[37]        -Inf         Inf  -1.1107210        -Inf         NaN        -Inf
-[43]         NaN         Inf  -4.3043414         NaN        -Inf -11.1020998
-[49]        -Inf         NaN         NaN        -Inf        -Inf  -1.9092287
-[55]        -Inf         NaN         NaN        -Inf         Inf  -0.8027754
-Warning message:
-In dgamma(c(-1, 0, 1), c(-1, 0, 0.2, 2:5), rep(c(-1, 0, 0.1, 0.9,  :
-  NaNs produced
+In pbinom(0, 10, 10, lower.tail = FALSE, log.p = TRUE) : NaNs produced
 
-##com.oracle.truffle.r.test.library.stats.TestStatFunctions.testFunctions31#Output.IgnoreWhitespace#
-#set.seed(1); dgamma(c(NA, NaN, 1/0, -1/0), 2, 2, log=FALSE)
-[1]  NA NaN   0   0
-
-##com.oracle.truffle.r.test.library.stats.TestStatFunctions.testFunctions31#Output.IgnoreWhitespace#
-#set.seed(1); dlnorm(0, c(0.0653, 0.000123, 32e-80, 8833, 79e70), c(0.0653, 0.000123, 32e-80, 8833, 79e70, 0, -1), log=FALSE)
-[1]   0   0   0   0   0   0 NaN
+##com.oracle.truffle.r.test.library.stats.TestStatFunctions.testFunctions32#Output.MayIgnoreWarningContext#
+#set.seed(1); pbinom(0, 10, 10, lower.tail=TRUE, log.p=FALSE)
+[1] NaN
 Warning message:
-In dlnorm(0, c(0.0653, 0.000123, 3.2e-79, 8833, 7.9e+71), c(0.0653,  :
-  NaNs produced
-
-##com.oracle.truffle.r.test.library.stats.TestStatFunctions.testFunctions31#Output.IgnoreWhitespace#
-#set.seed(1); dlnorm(0, c(NA, 0, NaN, 1/0, -1/0), c(NaN, NaN, NA, 0, 1/0, -1/0), log=FALSE)
-[1]  NA NaN  NA   0   0  NA
-
-##com.oracle.truffle.r.test.library.stats.TestStatFunctions.testFunctions31#Output.IgnoreWhitespace#
-#set.seed(1); dlnorm(10, 10, 10, log=TRUE)
-[1] -5.82036
-
-##com.oracle.truffle.r.test.library.stats.TestStatFunctions.testFunctions31#Output.IgnoreWhitespace#
-#set.seed(1); dlnorm(3, 3, 3, log=FALSE)
-[1] 0.03626103
+In pbinom(0, 10, 10, lower.tail = TRUE, log.p = FALSE) : NaNs produced
 
-##com.oracle.truffle.r.test.library.stats.TestStatFunctions.testFunctions31#Output.IgnoreWhitespace#
-#set.seed(1); dlnorm(c(-1, 0, 1), c(-1, 0, 0.2, 2:5), rep(c(-1, 0, 0.1, 0.9, 3), 12), log=FALSE)
- [1]           NaN  0.000000e+00  5.399097e-01  0.000000e+00  0.000000e+00
- [6]           NaN  0.000000e+00  0.000000e+00  4.432692e-01  0.000000e+00
-[11]           NaN  0.000000e+00  0.000000e+00  0.000000e+00  1.257944e-01
-[16]           NaN  0.000000e+00  5.520948e-87  0.000000e+00  0.000000e+00
-[21]           NaN  0.000000e+00  0.000000e+00  4.324583e-01  0.000000e+00
-[26]           NaN  0.000000e+00  0.000000e+00  0.000000e+00  1.329808e-01
-[31]           NaN  0.000000e+00 1.473646e-195  0.000000e+00  0.000000e+00
-[36]           NaN  0.000000e+00  0.000000e+00  3.752628e-02  0.000000e+00
-[41]           NaN  0.000000e+00  0.000000e+00  0.000000e+00  1.326856e-01
-[46]           NaN  0.000000e+00  0.000000e+00  0.000000e+00  0.000000e+00
-[51]           NaN  0.000000e+00  0.000000e+00  1.713643e-03  0.000000e+00
-[56]           NaN  0.000000e+00  0.000000e+00  0.000000e+00  1.064827e-01
+##com.oracle.truffle.r.test.library.stats.TestStatFunctions.testFunctions32#Output.MayIgnoreWarningContext#
+#set.seed(1); pbinom(0, 10, 10, lower.tail=TRUE, log.p=TRUE)
+[1] NaN
 Warning message:
-In dlnorm(c(-1, 0, 1), c(-1, 0, 0.2, 2:5), rep(c(-1, 0, 0.1, 0.9,  :
+In pbinom(0, 10, 10, lower.tail = TRUE, log.p = TRUE) : NaNs produced
+
+##com.oracle.truffle.r.test.library.stats.TestStatFunctions.testFunctions32#Output.MayIgnoreWarningContext#
+#set.seed(1); pbinom(0, c(0.0653, 0.000123, 32e-80, 8833, 79e70, 0, -1), rep(c(0.0653, 0.000123, 32e-80, 8833, 79e70), 7), lower.tail=FALSE, log.p=FALSE)
+ [1]          NaN          NaN 0.000000e+00          NaN          NaN
+ [6] 0.000000e+00          NaN          NaN          NaN          NaN
+[11] 1.000000e+00 1.000000e+00 0.000000e+00          NaN          NaN
+[16]          NaN 0.000000e+00 2.826560e-75          NaN          NaN
+[21]          NaN          NaN          NaN          NaN          NaN
+[26] 1.000000e+00 0.000000e+00          NaN          NaN          NaN
+[31] 0.000000e+00 6.626134e-01 2.528000e-07          NaN          NaN
+There were 11 warnings (use warnings() to see them)
+
+##com.oracle.truffle.r.test.library.stats.TestStatFunctions.testFunctions32#Output.MayIgnoreWarningContext#
+#set.seed(1); pbinom(0, c(0.0653, 0.000123, 32e-80, 8833, 79e70, 0, -1), rep(c(0.0653, 0.000123, 32e-80, 8833, 79e70), 7), lower.tail=FALSE, log.p=TRUE)
+ [1]            NaN            NaN           -Inf            NaN            NaN
+ [6]           -Inf            NaN            NaN            NaN            NaN
+[11] -8.869919e-260   0.000000e+00           -Inf            NaN            NaN
+[16]            NaN           -Inf  -1.716548e+02            NaN            NaN
+[21]            NaN            NaN            NaN            NaN            NaN
+[26]   0.000000e+00           -Inf            NaN            NaN            NaN
+[31]           -Inf  -4.115636e-01  -1.519067e+01            NaN            NaN
+There were 11 warnings (use warnings() to see them)
+
+##com.oracle.truffle.r.test.library.stats.TestStatFunctions.testFunctions32#Output.MayIgnoreWarningContext#
+#set.seed(1); pbinom(0, c(0.0653, 0.000123, 32e-80, 8833, 79e70, 0, -1), rep(c(0.0653, 0.000123, 32e-80, 8833, 79e70), 7), lower.tail=TRUE, log.p=FALSE)
+ [1]           NaN           NaN  1.000000e+00           NaN           NaN
+ [6]  1.000000e+00           NaN           NaN           NaN           NaN
+[11] 8.869919e-260  0.000000e+00  1.000000e+00           NaN           NaN
+[16]           NaN  1.000000e+00  1.000000e+00           NaN           NaN
+[21]           NaN           NaN           NaN           NaN           NaN
+[26]  0.000000e+00  1.000000e+00           NaN           NaN           NaN
+[31]  1.000000e+00  3.373866e-01  9.999997e-01           NaN           NaN
+There were 11 warnings (use warnings() to see them)
+
+##com.oracle.truffle.r.test.library.stats.TestStatFunctions.testFunctions32#Output.MayIgnoreWarningContext#
+#set.seed(1); pbinom(0, c(0.0653, 0.000123, 32e-80, 8833, 79e70, 0, -1), rep(c(0.0653, 0.000123, 32e-80, 8833, 79e70), 7), lower.tail=TRUE, log.p=TRUE)
+ [1]           NaN           NaN  0.000000e+00           NaN           NaN
+ [6]  0.000000e+00           NaN           NaN           NaN           NaN
+[11] -5.964895e+02 -9.717598e+67  0.000000e+00           NaN           NaN
+[16]           NaN  0.000000e+00 -2.826560e-75           NaN           NaN
+[21]           NaN           NaN           NaN           NaN           NaN
+[26] -5.334843e+70  0.000000e+00           NaN           NaN           NaN
+[31]  0.000000e+00 -1.086526e+00 -2.528000e-07           NaN           NaN
+There were 11 warnings (use warnings() to see them)
+
+##com.oracle.truffle.r.test.library.stats.TestStatFunctions.testFunctions32#Output.MayIgnoreWarningContext#
+#set.seed(1); pbinom(c(-1, 0, 0.2, 2), c(-1, 0, 0.1, 0.9, 3), rep(c(-1, 0, 1, 0.1, -0.1, 0.0001), 20), lower.tail=FALSE, log.p=FALSE)
+  [1]        NaN 0.0000e+00        NaN        NaN        NaN        NaN
+  [7]        NaN        NaN        NaN 2.7100e-01        NaN 0.0000e+00
+ [13]        NaN        NaN 1.0000e+00        NaN        NaN        NaN
+ [19]        NaN 0.0000e+00        NaN 0.0000e+00        NaN        NaN
+ [25]        NaN        NaN 0.0000e+00        NaN        NaN 2.9997e-04
+ [31]        NaN 0.0000e+00        NaN        NaN        NaN        NaN
+ [37]        NaN        NaN        NaN 1.0000e-03        NaN 0.0000e+00
+ [43]        NaN        NaN 1.0000e+00        NaN        NaN        NaN
+ [49]        NaN 0.0000e+00        NaN 0.0000e+00        NaN        NaN
+ [55]        NaN        NaN 1.0000e+00        NaN        NaN 1.0000e-12
+ [61]        NaN 0.0000e+00        NaN        NaN        NaN        NaN
+ [67]        NaN        NaN        NaN 2.7100e-01        NaN 0.0000e+00
+ [73]        NaN        NaN 1.0000e+00        NaN        NaN        NaN
+ [79]        NaN 0.0000e+00        NaN 0.0000e+00        NaN        NaN
+ [85]        NaN        NaN 0.0000e+00        NaN        NaN 2.9997e-04
+ [91]        NaN 0.0000e+00        NaN        NaN        NaN        NaN
+ [97]        NaN        NaN        NaN 1.0000e-03        NaN 0.0000e+00
+[103]        NaN        NaN 1.0000e+00        NaN        NaN        NaN
+[109]        NaN 0.0000e+00        NaN 0.0000e+00        NaN        NaN
+[115]        NaN        NaN 1.0000e+00        NaN        NaN 1.0000e-12
+There were 49 warnings (use warnings() to see them)
+
+##com.oracle.truffle.r.test.library.stats.TestStatFunctions.testFunctions32#Output.MayIgnoreWarningContext#
+#set.seed(1); pbinom(c(-1, 0, 0.2, 2), c(-1, 0, 0.1, 0.9, 3), rep(c(-1, 0, 1, 0.1, -0.1, 0.0001), 20), lower.tail=FALSE, log.p=TRUE)
+  [1]        NaN       -Inf        NaN        NaN        NaN        NaN
+  [7]        NaN        NaN        NaN  -1.305636        NaN       -Inf
+ [13]        NaN        NaN   0.000000        NaN        NaN        NaN
+ [19]        NaN       -Inf        NaN       -Inf        NaN        NaN
+ [25]        NaN        NaN       -Inf        NaN        NaN  -8.111828
+ [31]        NaN       -Inf        NaN        NaN        NaN        NaN
+ [37]        NaN        NaN        NaN  -6.907755        NaN       -Inf
+ [43]        NaN        NaN   0.000000        NaN        NaN        NaN
+ [49]        NaN       -Inf        NaN       -Inf        NaN        NaN
+ [55]        NaN        NaN   0.000000        NaN        NaN -27.631021
+ [61]        NaN       -Inf        NaN        NaN        NaN        NaN
+ [67]        NaN        NaN        NaN  -1.305636        NaN       -Inf
+ [73]        NaN        NaN   0.000000        NaN        NaN        NaN
+ [79]        NaN       -Inf        NaN       -Inf        NaN        NaN
+ [85]        NaN        NaN       -Inf        NaN        NaN  -8.111828
+ [91]        NaN       -Inf        NaN        NaN        NaN        NaN
+ [97]        NaN        NaN        NaN  -6.907755        NaN       -Inf
+[103]        NaN        NaN   0.000000        NaN        NaN        NaN
+[109]        NaN       -Inf        NaN       -Inf        NaN        NaN
+[115]        NaN        NaN   0.000000        NaN        NaN -27.631021
+There were 49 warnings (use warnings() to see them)
+
+##com.oracle.truffle.r.test.library.stats.TestStatFunctions.testFunctions32#Output.MayIgnoreWarningContext#
+#set.seed(1); pbinom(c(-1, 0, 0.2, 2), c(-1, 0, 0.1, 0.9, 3), rep(c(-1, 0, 1, 0.1, -0.1, 0.0001), 20), lower.tail=TRUE, log.p=FALSE)
+  [1]    NaN 1.0000    NaN    NaN    NaN    NaN    NaN    NaN    NaN 0.7290
+ [11]    NaN 1.0000    NaN    NaN 0.0000    NaN    NaN    NaN    NaN 1.0000
+ [21]    NaN 1.0000    NaN    NaN    NaN    NaN 1.0000    NaN    NaN 0.9997
+ [31]    NaN 1.0000    NaN    NaN    NaN    NaN    NaN    NaN    NaN 0.9990
+ [41]    NaN 1.0000    NaN    NaN 0.0000    NaN    NaN    NaN    NaN 1.0000
+ [51]    NaN 1.0000    NaN    NaN    NaN    NaN 0.0000    NaN    NaN 1.0000
+ [61]    NaN 1.0000    NaN    NaN    NaN    NaN    NaN    NaN    NaN 0.7290
+ [71]    NaN 1.0000    NaN    NaN 0.0000    NaN    NaN    NaN    NaN 1.0000
+ [81]    NaN 1.0000    NaN    NaN    NaN    NaN 1.0000    NaN    NaN 0.9997
+ [91]    NaN 1.0000    NaN    NaN    NaN    NaN    NaN    NaN    NaN 0.9990
+[101]    NaN 1.0000    NaN    NaN 0.0000    NaN    NaN    NaN    NaN 1.0000
+[111]    NaN 1.0000    NaN    NaN    NaN    NaN 0.0000    NaN    NaN 1.0000
+There were 49 warnings (use warnings() to see them)
+
+##com.oracle.truffle.r.test.library.stats.TestStatFunctions.testFunctions32#Output.MayIgnoreWarningContext#
+#set.seed(1); pbinom(c(-1, 0, 0.2, 2), c(-1, 0, 0.1, 0.9, 3), rep(c(-1, 0, 1, 0.1, -0.1, 0.0001), 20), lower.tail=TRUE, log.p=TRUE)
+  [1]           NaN  0.000000e+00           NaN           NaN           NaN
+  [6]           NaN           NaN           NaN           NaN -3.160815e-01
+ [11]           NaN  0.000000e+00           NaN           NaN          -Inf
+ [16]           NaN           NaN           NaN           NaN  0.000000e+00
+ [21]           NaN  0.000000e+00           NaN           NaN           NaN
+ [26]           NaN  0.000000e+00           NaN           NaN -3.000150e-04
+ [31]           NaN  0.000000e+00           NaN           NaN           NaN
+ [36]           NaN           NaN           NaN           NaN -1.000500e-03
+ [41]           NaN  0.000000e+00           NaN           NaN          -Inf
+ [46]           NaN           NaN           NaN           NaN  0.000000e+00
+ [51]           NaN  0.000000e+00           NaN           NaN           NaN
+ [56]           NaN          -Inf           NaN           NaN -1.000000e-12
+ [61]           NaN  0.000000e+00           NaN           NaN           NaN
+ [66]           NaN           NaN           NaN           NaN -3.160815e-01
+ [71]           NaN  0.000000e+00           NaN           NaN          -Inf
+ [76]           NaN           NaN           NaN           NaN  0.000000e+00
+ [81]           NaN  0.000000e+00           NaN           NaN           NaN
+ [86]           NaN  0.000000e+00           NaN           NaN -3.000150e-04
+ [91]           NaN  0.000000e+00           NaN           NaN           NaN
+ [96]           NaN           NaN           NaN           NaN -1.000500e-03
+[101]           NaN  0.000000e+00           NaN           NaN          -Inf
+[106]           NaN           NaN           NaN           NaN  0.000000e+00
+[111]           NaN  0.000000e+00           NaN           NaN           NaN
+[116]           NaN          -Inf           NaN           NaN -1.000000e-12
+There were 49 warnings (use warnings() to see them)
+
+##com.oracle.truffle.r.test.library.stats.TestStatFunctions.testFunctions32#Output.MayIgnoreWarningContext#
+#set.seed(1); pbinom(c(NA, 0, NaN, 1/0, -1/0), rep(c(1, 0, 0.1), 5), rep(c(1, 0, 0.1), 5))
+ [1]  NA   1 NaN   1   0  NA   0 NaN NaN   0  NA NaN NaN   1 NaN
+Warning messages:
+1: In pbinom(c(NA, 0, NaN, 1/0, -1/0), rep(c(1, 0, 0.1), 5), rep(c(1,  :
+  non-integer n = 0.100000
+2: In pbinom(c(NA, 0, NaN, 1/0, -1/0), rep(c(1, 0, 0.1), 5), rep(c(1,  :
+  non-integer n = 0.100000
+3: In pbinom(c(NA, 0, NaN, 1/0, -1/0), rep(c(1, 0, 0.1), 5), rep(c(1,  :
+  non-integer n = 0.100000
+4: In pbinom(c(NA, 0, NaN, 1/0, -1/0), rep(c(1, 0, 0.1), 5), rep(c(1,  :
   NaNs produced
 
-##com.oracle.truffle.r.test.library.stats.TestStatFunctions.testFunctions31#Output.IgnoreWhitespace#
-#set.seed(1); dlnorm(c(-1, 0, 1), c(-1, 0, 0.2, 2:5), rep(c(-1, 0, 0.1, 0.9, 3), 12), log=TRUE)
- [1]          NaN         -Inf   -0.6163534         -Inf         -Inf
- [6]          NaN         -Inf         -Inf   -0.8135780         -Inf
-[11]          NaN         -Inf         -Inf         -Inf   -2.0731064
-[16]          NaN         -Inf -198.6163534         -Inf         -Inf
-[21]          NaN         -Inf         -Inf   -0.8382694         -Inf
-[26]          NaN         -Inf         -Inf         -Inf   -2.0175508
-[31]          NaN         -Inf -448.6163534         -Inf         -Inf
-[36]          NaN         -Inf         -Inf   -3.2827138         -Inf
-[41]          NaN         -Inf         -Inf         -Inf   -2.0197730
-[46]          NaN         -Inf -798.6163534         -Inf         -Inf
-[51]          NaN         -Inf         -Inf   -6.3691336         -Inf
-[56]          NaN         -Inf         -Inf         -Inf   -2.2397730
+##com.oracle.truffle.r.test.library.stats.TestStatFunctions.testFunctions32#Output.MayIgnoreWarningContext#
+#set.seed(1); pbinom(rep(c(1, 0, 0.1), 5), c(NA, 0, NaN, 1/0, -1/0), rep(c(1, 0, 0.1), 5))
+ [1]  NA   1 NaN NaN NaN  NA   1 NaN NaN NaN  NA   1 NaN NaN NaN
 Warning message:
-In dlnorm(c(-1, 0, 1), c(-1, 0, 0.2, 2:5), rep(c(-1, 0, 0.1, 0.9,  :
+In pbinom(rep(c(1, 0, 0.1), 5), c(NA, 0, NaN, 1/0, -1/0), rep(c(1,  :
   NaNs produced
 
-##com.oracle.truffle.r.test.library.stats.TestStatFunctions.testFunctions31#Output.IgnoreWhitespace#
-#set.seed(1); dlnorm(c(NA, NaN, 1/0, -1/0), 2, 2, log=FALSE)
-[1]  NA NaN   0   0
+##com.oracle.truffle.r.test.library.stats.TestStatFunctions.testFunctions32#Output.MayIgnoreWarningContext#
+#set.seed(1); pbinom(rep(c(1, 0, 0.1), 5), rep(c(1, 0, 0.1), 5), c(NA, 0, NaN, 1/0, -1/0))
+ [1]  NA   1 NaN NaN NaN  NA   1 NaN NaN NaN  NA NaN NaN NaN NaN
+Warning messages:
+1: In pbinom(rep(c(1, 0, 0.1), 5), rep(c(1, 0, 0.1), 5), c(NA, 0, NaN,  :
+  non-integer n = 0.100000
+2: In pbinom(rep(c(1, 0, 0.1), 5), rep(c(1, 0, 0.1), 5), c(NA, 0, NaN,  :
+  NaNs produced
 
-##com.oracle.truffle.r.test.library.stats.TestStatFunctions.testFunctions32#Output.IgnoreWhitespace#
-#set.seed(1); pbeta(0, 10, 10, lower.tail=FALSE, log.p=FALSE)
+##com.oracle.truffle.r.test.library.stats.TestStatFunctions.testFunctions32#Output.MayIgnoreWarningContext#
+#set.seed(1); pf(0, 10, 10, lower.tail=FALSE, log.p=FALSE)
 [1] 1
 
-##com.oracle.truffle.r.test.library.stats.TestStatFunctions.testFunctions32#Output.IgnoreWhitespace#
-#set.seed(1); pbeta(0, 10, 10, lower.tail=FALSE, log.p=TRUE)
+##com.oracle.truffle.r.test.library.stats.TestStatFunctions.testFunctions32#Output.MayIgnoreWarningContext#
+#set.seed(1); pf(0, 10, 10, lower.tail=FALSE, log.p=TRUE)
 [1] 0
 
-##com.oracle.truffle.r.test.library.stats.TestStatFunctions.testFunctions32#Output.IgnoreWhitespace#
-#set.seed(1); pbeta(0, 10, 10, lower.tail=TRUE, log.p=FALSE)
+##com.oracle.truffle.r.test.library.stats.TestStatFunctions.testFunctions32#Output.MayIgnoreWarningContext#
+#set.seed(1); pf(0, 10, 10, lower.tail=TRUE, log.p=FALSE)
 [1] 0
 
-##com.oracle.truffle.r.test.library.stats.TestStatFunctions.testFunctions32#Output.IgnoreWhitespace#
-#set.seed(1); pbeta(0, 10, 10, lower.tail=TRUE, log.p=TRUE)
+##com.oracle.truffle.r.test.library.stats.TestStatFunctions.testFunctions32#Output.MayIgnoreWarningContext#
+#set.seed(1); pf(0, 10, 10, lower.tail=TRUE, log.p=TRUE)
 [1] -Inf
 
-##com.oracle.truffle.r.test.library.stats.TestStatFunctions.testFunctions32#Output.IgnoreWhitespace#
-#set.seed(1); pbeta(0, c(0.0653, 0.000123, 32e-80, 8833, 79e70, 0, -1), rep(c(0.0653, 0.000123, 32e-80, 8833, 79e70), 7), lower.tail=FALSE, log.p=FALSE)
- [1]   1   1   1   1   1   1 NaN   1   1   1   1   1   1 NaN   1   1   1   1   1
-[20]   1 NaN   1   1   1   1   1   1 NaN   1   1   1   1   1   1 NaN
+##com.oracle.truffle.r.test.library.stats.TestStatFunctions.testFunctions32#Output.MayIgnoreWarningContext#
+#set.seed(1); pf(0, c(0.0653, 0.000123, 32e-80, 8833, 79e70, 0, -1), rep(c(0.0653, 0.000123, 32e-80, 8833, 79e70), 7), lower.tail=FALSE, log.p=FALSE)
+ [1]   1   1   1   1   1 NaN NaN   1   1   1   1   1 NaN NaN   1   1   1   1   1
+[20] NaN NaN   1   1   1   1   1 NaN NaN   1   1   1   1   1 NaN NaN
 Warning message:
-In pbeta(0, c(0.0653, 0.000123, 3.2e-79, 8833, 7.9e+71, 0, -1),  :
+In pf(0, c(0.0653, 0.000123, 3.2e-79, 8833, 7.9e+71, 0, -1), rep(c(0.0653,  :
   NaNs produced
 
-##com.oracle.truffle.r.test.library.stats.TestStatFunctions.testFunctions32#Output.IgnoreWhitespace#
-#set.seed(1); pbeta(0, c(0.0653, 0.000123, 32e-80, 8833, 79e70, 0, -1), rep(c(0.0653, 0.000123, 32e-80, 8833, 79e70), 7), lower.tail=FALSE, log.p=TRUE)
- [1]   0   0   0   0   0   0 NaN   0   0   0   0   0   0 NaN   0   0   0   0   0
-[20]   0 NaN   0   0   0   0   0   0 NaN   0   0   0   0   0   0 NaN
+##com.oracle.truffle.r.test.library.stats.TestStatFunctions.testFunctions32#Output.MayIgnoreWarningContext#
+#set.seed(1); pf(0, c(0.0653, 0.000123, 32e-80, 8833, 79e70, 0, -1), rep(c(0.0653, 0.000123, 32e-80, 8833, 79e70), 7), lower.tail=FALSE, log.p=TRUE)
+ [1]   0   0   0   0   0 NaN NaN   0   0   0   0   0 NaN NaN   0   0   0   0   0
+[20] NaN NaN   0   0   0   0   0 NaN NaN   0   0   0   0   0 NaN NaN
 Warning message:
-In pbeta(0, c(0.0653, 0.000123, 3.2e-79, 8833, 7.9e+71, 0, -1),  :
+In pf(0, c(0.0653, 0.000123, 3.2e-79, 8833, 7.9e+71, 0, -1), rep(c(0.0653,  :
   NaNs produced
 
-##com.oracle.truffle.r.test.library.stats.TestStatFunctions.testFunctions32#Output.IgnoreWhitespace#
-#set.seed(1); pbeta(0, c(0.0653, 0.000123, 32e-80, 8833, 79e70, 0, -1), rep(c(0.0653, 0.000123, 32e-80, 8833, 79e70), 7), lower.tail=TRUE, log.p=FALSE)
- [1]   0   0   0   0   0   0 NaN   0   0   0   0   0   0 NaN   0   0   0   0   0
-[20]   0 NaN   0   0   0   0   0   0 NaN   0   0   0   0   0   0 NaN
+##com.oracle.truffle.r.test.library.stats.TestStatFunctions.testFunctions32#Output.MayIgnoreWarningContext#
+#set.seed(1); pf(0, c(0.0653, 0.000123, 32e-80, 8833, 79e70, 0, -1), rep(c(0.0653, 0.000123, 32e-80, 8833, 79e70), 7), lower.tail=TRUE, log.p=FALSE)
+ [1]   0   0   0   0   0 NaN NaN   0   0   0   0   0 NaN NaN   0   0   0   0   0
+[20] NaN NaN   0   0   0   0   0 NaN NaN   0   0   0   0   0 NaN NaN
 Warning message:
-In pbeta(0, c(0.0653, 0.000123, 3.2e-79, 8833, 7.9e+71, 0, -1),  :
+In pf(0, c(0.0653, 0.000123, 3.2e-79, 8833, 7.9e+71, 0, -1), rep(c(0.0653,  :
   NaNs produced
 
-##com.oracle.truffle.r.test.library.stats.TestStatFunctions.testFunctions32#Output.IgnoreWhitespace#
-#set.seed(1); pbeta(0, c(0.0653, 0.000123, 32e-80, 8833, 79e70, 0, -1), rep(c(0.0653, 0.000123, 32e-80, 8833, 79e70), 7), lower.tail=TRUE, log.p=TRUE)
- [1] -Inf -Inf -Inf -Inf -Inf -Inf  NaN -Inf -Inf -Inf -Inf -Inf -Inf  NaN -Inf
-[16] -Inf -Inf -Inf -Inf -Inf  NaN -Inf -Inf -Inf -Inf -Inf -Inf  NaN -Inf -Inf
-[31] -Inf -Inf -Inf -Inf  NaN
+##com.oracle.truffle.r.test.library.stats.TestStatFunctions.testFunctions32#Output.MayIgnoreWarningContext#
+#set.seed(1); pf(0, c(0.0653, 0.000123, 32e-80, 8833, 79e70, 0, -1), rep(c(0.0653, 0.000123, 32e-80, 8833, 79e70), 7), lower.tail=TRUE, log.p=TRUE)
+ [1] -Inf -Inf -Inf -Inf -Inf  NaN  NaN -Inf -Inf -Inf -Inf -Inf  NaN  NaN -Inf
+[16] -Inf -Inf -Inf -Inf  NaN  NaN -Inf -Inf -Inf -Inf -Inf  NaN  NaN -Inf -Inf
+[31] -Inf -Inf -Inf  NaN  NaN
 Warning message:
-In pbeta(0, c(0.0653, 0.000123, 3.2e-79, 8833, 7.9e+71, 0, -1),  :
+In pf(0, c(0.0653, 0.000123, 3.2e-79, 8833, 7.9e+71, 0, -1), rep(c(0.0653,  :
   NaNs produced
 
-##com.oracle.truffle.r.test.library.stats.TestStatFunctions.testFunctions32#Output.IgnoreWhitespace#
-#set.seed(1); pbeta(c(-1, 0, 0.2, 2), c(-1, 0, 0.1, 0.9, 3), rep(c(-1, 0, 1, 0.1, -0.1, 0.0001), 20), lower.tail=FALSE, log.p=FALSE)
-  [1]       NaN 1.0000000 0.1486601 0.0000000       NaN       NaN       NaN
-  [8] 0.0000000 1.0000000 1.0000000       NaN 0.0000000       NaN 1.0000000
- [15] 0.9920000       NaN       NaN 1.0000000       NaN 0.0000000       NaN
- [22] 1.0000000       NaN 0.0000000       NaN       NaN 0.0000000 0.0000000
- [29]       NaN 1.0000000       NaN 0.0000000 1.0000000 1.0000000       NaN
- [36]       NaN       NaN 1.0000000 0.7650762 0.0000000       NaN 1.0000000
- [43]       NaN 0.0000000 1.0000000       NaN       NaN 0.0000000       NaN
- [50] 1.0000000       NaN 0.0000000       NaN 1.0000000       NaN       NaN
- [57] 1.0000000 1.0000000       NaN 0.0000000       NaN 1.0000000 0.1486601
- [64] 0.0000000       NaN       NaN       NaN 0.0000000 1.0000000 1.0000000
- [71]       NaN 0.0000000       NaN 1.0000000 0.9920000       NaN       NaN
- [78] 1.0000000       NaN 0.0000000       NaN 1.0000000       NaN 0.0000000
- [85]       NaN       NaN 0.0000000 0.0000000       NaN 1.0000000       NaN
- [92] 0.0000000 1.0000000 1.0000000       NaN       NaN       NaN 1.0000000
- [99] 0.7650762 0.0000000       NaN 1.0000000       NaN 0.0000000 1.0000000
-[106]       NaN       NaN 0.0000000       NaN 1.0000000       NaN 0.0000000
-[113]       NaN 1.0000000       NaN       NaN 1.0000000 1.0000000       NaN
-[120] 0.0000000
-Warning message:
-In pbeta(c(-1, 0, 0.2, 2), c(-1, 0, 0.1, 0.9, 3), rep(c(-1, 0, 1,  :
+##com.oracle.truffle.r.test.library.stats.TestStatFunctions.testFunctions32#Output.MayIgnoreWarningContext#
+#set.seed(1); pf(c(-1, 0, 0.2, 2), c(-1, 0, 0.1, 0.9, 3), rep(c(-1, 0, 1, 0.1, -0.1, 0.0001), 20), lower.tail=FALSE, log.p=FALSE)
+  [1]       NaN       NaN 0.2301826 0.7995678       NaN       NaN       NaN
+  [8]       NaN 1.0000000 1.0000000       NaN       NaN       NaN       NaN
+ [15] 0.8886328       NaN       NaN 1.0000000       NaN       NaN       NaN
+ [22]       NaN       NaN 0.9994274       NaN       NaN       NaN 0.4838017
+ [29]       NaN 1.0000000       NaN       NaN 1.0000000 1.0000000       NaN
+ [36]       NaN       NaN       NaN 0.7109050 0.8385293       NaN       NaN
+ [43]       NaN       NaN 1.0000000       NaN       NaN 0.9986254       NaN
+ [50]       NaN       NaN       NaN       NaN 1.0000000       NaN       NaN
+ [57]       NaN 1.0000000       NaN 0.9994807       NaN       NaN 0.2301826
+ [64] 0.7995678       NaN       NaN       NaN       NaN 1.0000000 1.0000000
+ [71]       NaN       NaN       NaN       NaN 0.8886328       NaN       NaN
+ [78] 1.0000000       NaN       NaN       NaN       NaN       NaN 0.9994274
+ [85]       NaN       NaN       NaN 0.4838017       NaN 1.0000000       NaN
+ [92]       NaN 1.0000000 1.0000000       NaN       NaN       NaN       NaN
+ [99] 0.7109050 0.8385293       NaN       NaN       NaN       NaN 1.0000000
+[106]       NaN       NaN 0.9986254       NaN       NaN       NaN       NaN
+[113]       NaN 1.0000000       NaN       NaN       NaN 1.0000000       NaN
+[120] 0.9994807
+Warning message:
+In pf(c(-1, 0, 0.2, 2), c(-1, 0, 0.1, 0.9, 3), rep(c(-1, 0, 1, 0.1,  :
   NaNs produced
 
-##com.oracle.truffle.r.test.library.stats.TestStatFunctions.testFunctions32#Output.IgnoreWhitespace#
-#set.seed(1); pbeta(c(-1, 0, 0.2, 2), c(-1, 0, 0.1, 0.9, 3), rep(c(-1, 0, 1, 0.1, -0.1, 0.0001), 20), lower.tail=FALSE, log.p=TRUE)
-  [1]          NaN  0.000000000 -1.906092939         -Inf          NaN
-  [6]          NaN          NaN         -Inf  0.000000000  0.000000000
- [11]          NaN         -Inf          NaN  0.000000000 -0.008032172
- [16]          NaN          NaN  0.000000000          NaN         -Inf
- [21]          NaN  0.000000000          NaN         -Inf          NaN
- [26]          NaN         -Inf         -Inf          NaN  0.000000000
- [31]          NaN         -Inf  0.000000000  0.000000000          NaN
- [36]          NaN          NaN  0.000000000 -0.267779827         -Inf
- [41]          NaN  0.000000000          NaN         -Inf  0.000000000
- [46]          NaN          NaN         -Inf          NaN  0.000000000
- [51]          NaN         -Inf          NaN  0.000000000          NaN
- [56]          NaN  0.000000000  0.000000000          NaN         -Inf
- [61]          NaN  0.000000000 -1.906092939         -Inf          NaN
- [66]          NaN          NaN         -Inf  0.000000000  0.000000000
- [71]          NaN         -Inf          NaN  0.000000000 -0.008032172
- [76]          NaN          NaN  0.000000000          NaN         -Inf
- [81]          NaN  0.000000000          NaN         -Inf          NaN
- [86]          NaN         -Inf         -Inf          NaN  0.000000000
- [91]          NaN         -Inf  0.000000000  0.000000000          NaN
- [96]          NaN          NaN  0.000000000 -0.267779827         -Inf
-[101]          NaN  0.000000000          NaN         -Inf  0.000000000
-[106]          NaN          NaN         -Inf          NaN  0.000000000
-[111]          NaN         -Inf          NaN  0.000000000          NaN
-[116]          NaN  0.000000000  0.000000000          NaN         -Inf
-Warning message:
-In pbeta(c(-1, 0, 0.2, 2), c(-1, 0, 0.1, 0.9, 3), rep(c(-1, 0, 1,  :
+##com.oracle.truffle.r.test.library.stats.TestStatFunctions.testFunctions32#Output.MayIgnoreWarningContext#
+#set.seed(1); pf(c(-1, 0, 0.2, 2), c(-1, 0, 0.1, 0.9, 3), rep(c(-1, 0, 1, 0.1, -0.1, 0.0001), 20), lower.tail=FALSE, log.p=TRUE)
+  [1]           NaN           NaN -1.4688821632 -0.2236838870           NaN
+  [6]           NaN           NaN           NaN  0.0000000000  0.0000000000
+ [11]           NaN           NaN           NaN           NaN -0.1180711262
+ [16]           NaN           NaN  0.0000000000           NaN           NaN
+ [21]           NaN           NaN           NaN -0.0005727184           NaN
+ [26]           NaN           NaN -0.7260801256           NaN  0.0000000000
+ [31]           NaN           NaN  0.0000000000  0.0000000000           NaN
+ [36]           NaN           NaN           NaN -0.3412165338 -0.1761057482
+ [41]           NaN           NaN           NaN           NaN  0.0000000000
+ [46]           NaN           NaN -0.0013755783           NaN           NaN
+ [51]           NaN           NaN           NaN  0.0000000000           NaN
+ [56]           NaN           NaN  0.0000000000           NaN -0.0005194218
+ [61]           NaN           NaN -1.4688821632 -0.2236838870           NaN
+ [66]           NaN           NaN           NaN  0.0000000000  0.0000000000
+ [71]           NaN           NaN           NaN           NaN -0.1180711262
+ [76]           NaN           NaN  0.0000000000           NaN           NaN
+ [81]           NaN           NaN           NaN -0.0005727184           NaN
+ [86]           NaN           NaN -0.7260801256           NaN  0.0000000000
+ [91]           NaN           NaN  0.0000000000  0.0000000000           NaN
+ [96]           NaN           NaN           NaN -0.3412165338 -0.1761057482
+[101]           NaN           NaN           NaN           NaN  0.0000000000
+[106]           NaN           NaN -0.0013755783           NaN           NaN
+[111]           NaN           NaN           NaN  0.0000000000           NaN
+[116]           NaN           NaN  0.0000000000           NaN -0.0005194218
+Warning message:
+In pf(c(-1, 0, 0.2, 2), c(-1, 0, 0.1, 0.9, 3), rep(c(-1, 0, 1, 0.1,  :
   NaNs produced
 
-##com.oracle.truffle.r.test.library.stats.TestStatFunctions.testFunctions32#Output.IgnoreWhitespace#
-#set.seed(1); pbeta(c(-1, 0, 0.2, 2), c(-1, 0, 0.1, 0.9, 3), rep(c(-1, 0, 1, 0.1, -0.1, 0.0001), 20), lower.tail=TRUE, log.p=FALSE)
-  [1]       NaN 0.0000000 0.8513399 1.0000000       NaN       NaN       NaN
-  [8] 1.0000000 0.0000000 0.0000000       NaN 1.0000000       NaN 0.0000000
- [15] 0.0080000       NaN       NaN 0.0000000       NaN 1.0000000       NaN
- [22] 0.0000000       NaN 1.0000000       NaN       NaN 1.0000000 1.0000000
- [29]       NaN 0.0000000       NaN 1.0000000 0.0000000 0.0000000       NaN
- [36]       NaN       NaN 0.0000000 0.2349238 1.0000000       NaN 0.0000000
- [43]       NaN 1.0000000 0.0000000       NaN       NaN 1.0000000       NaN
- [50] 0.0000000       NaN 1.0000000       NaN 0.0000000       NaN       NaN
- [57] 0.0000000 0.0000000       NaN 1.0000000       NaN 0.0000000 0.8513399
- [64] 1.0000000       NaN       NaN       NaN 1.0000000 0.0000000 0.0000000
- [71]       NaN 1.0000000       NaN 0.0000000 0.0080000       NaN       NaN
- [78] 0.0000000       NaN 1.0000000       NaN 0.0000000       NaN 1.0000000
- [85]       NaN       NaN 1.0000000 1.0000000       NaN 0.0000000       NaN
- [92] 1.0000000 0.0000000 0.0000000       NaN       NaN       NaN 0.0000000
- [99] 0.2349238 1.0000000       NaN 0.0000000       NaN 1.0000000 0.0000000
-[106]       NaN       NaN 1.0000000       NaN 0.0000000       NaN 1.0000000
-[113]       NaN 0.0000000       NaN       NaN 0.0000000 0.0000000       NaN
-[120] 1.0000000
-Warning message:
-In pbeta(c(-1, 0, 0.2, 2), c(-1, 0, 0.1, 0.9, 3), rep(c(-1, 0, 1,  :
+##com.oracle.truffle.r.test.library.stats.TestStatFunctions.testFunctions32#Output.MayIgnoreWarningContext#
+#set.seed(1); pf(c(-1, 0, 0.2, 2), c(-1, 0, 0.1, 0.9, 3), rep(c(-1, 0, 1, 0.1, -0.1, 0.0001), 20), lower.tail=TRUE, log.p=FALSE)
+  [1]          NaN          NaN 0.7698173519 0.2004321518          NaN
+  [6]          NaN          NaN          NaN 0.0000000000 0.0000000000
+ [11]          NaN          NaN          NaN          NaN 0.1113671547
+ [16]          NaN          NaN 0.0000000000          NaN          NaN
+ [21]          NaN          NaN          NaN 0.0005725544          NaN
+ [26]          NaN          NaN 0.5161982800          NaN 0.0000000000
+ [31]          NaN          NaN 0.0000000000 0.0000000000          NaN
+ [36]          NaN          NaN          NaN 0.2890950434 0.1614706943
+ [41]          NaN          NaN          NaN          NaN 0.0000000000
+ [46]          NaN          NaN 0.0013746326          NaN          NaN
+ [51]          NaN          NaN          NaN 0.0000000000          NaN
+ [56]          NaN          NaN 0.0000000000          NaN 0.0005192870
+ [61]          NaN          NaN 0.7698173519 0.2004321518          NaN
+ [66]          NaN          NaN          NaN 0.0000000000 0.0000000000
+ [71]          NaN          NaN          NaN          NaN 0.1113671547
+ [76]          NaN          NaN 0.0000000000          NaN          NaN
+ [81]          NaN          NaN          NaN 0.0005725544          NaN
+ [86]          NaN          NaN 0.5161982800          NaN 0.0000000000
+ [91]          NaN          NaN 0.0000000000 0.0000000000          NaN
+ [96]          NaN          NaN          NaN 0.2890950434 0.1614706943
+[101]          NaN          NaN          NaN          NaN 0.0000000000
+[106]          NaN          NaN 0.0013746326          NaN          NaN
+[111]          NaN          NaN          NaN 0.0000000000          NaN
+[116]          NaN          NaN 0.0000000000          NaN 0.0005192870
+Warning message:
+In pf(c(-1, 0, 0.2, 2), c(-1, 0, 0.1, 0.9, 3), rep(c(-1, 0, 1, 0.1,  :
   NaNs produced
 
-##com.oracle.truffle.r.test.library.stats.TestStatFunctions.testFunctions32#Output.IgnoreWhitespace#
-#set.seed(1); pbeta(c(-1, 0, 0.2, 2), c(-1, 0, 0.1, 0.9, 3), rep(c(-1, 0, 1, 0.1, -0.1, 0.0001), 20), lower.tail=TRUE, log.p=TRUE)
-  [1]        NaN       -Inf -0.1609438  0.0000000        NaN        NaN
-  [7]        NaN  0.0000000       -Inf       -Inf        NaN  0.0000000
- [13]        NaN       -Inf -4.8283137        NaN        NaN       -Inf
- [19]        NaN  0.0000000        NaN       -Inf        NaN  0.0000000
- [25]        NaN        NaN  0.0000000  0.0000000        NaN       -Inf
- [31]        NaN  0.0000000       -Inf       -Inf        NaN        NaN
- [37]        NaN       -Inf -1.4484941  0.0000000        NaN       -Inf
- [43]        NaN  0.0000000       -Inf        NaN        NaN  0.0000000
- [49]        NaN       -Inf        NaN  0.0000000        NaN       -Inf
- [55]        NaN        NaN       -Inf       -Inf        NaN  0.0000000
- [61]        NaN       -Inf -0.1609438  0.0000000        NaN        NaN
- [67]        NaN  0.0000000       -Inf       -Inf        NaN  0.0000000
- [73]        NaN       -Inf -4.8283137        NaN        NaN       -Inf
- [79]        NaN  0.0000000        NaN       -Inf        NaN  0.0000000
- [85]        NaN        NaN  0.0000000  0.0000000        NaN       -Inf
- [91]        NaN  0.0000000       -Inf       -Inf        NaN        NaN
- [97]        NaN       -Inf -1.4484941  0.0000000        NaN       -Inf
-[103]        NaN  0.0000000       -Inf        NaN        NaN  0.0000000
-[109]        NaN       -Inf        NaN  0.0000000        NaN       -Inf
-[115]        NaN        NaN       -Inf       -Inf        NaN  0.0000000
-Warning message:
-In pbeta(c(-1, 0, 0.2, 2), c(-1, 0, 0.1, 0.9, 3), rep(c(-1, 0, 1,  :
+##com.oracle.truffle.r.test.library.stats.TestStatFunctions.testFunctions32#Output.MayIgnoreWarningContext#
+#set.seed(1); pf(c(-1, 0, 0.2, 2), c(-1, 0, 0.1, 0.9, 3), rep(c(-1, 0, 1, 0.1, -0.1, 0.0001), 20), lower.tail=TRUE, log.p=TRUE)
+  [1]        NaN        NaN -0.2616020 -1.6072795        NaN        NaN
+  [7]        NaN        NaN       -Inf       -Inf        NaN        NaN
+ [13]        NaN        NaN -2.1949228        NaN        NaN       -Inf
+ [19]        NaN        NaN        NaN        NaN        NaN -7.4654027
+ [25]        NaN        NaN        NaN -0.6612643        NaN       -Inf
+ [31]        NaN        NaN       -Inf       -Inf        NaN        NaN
+ [37]        NaN        NaN -1.2409998 -1.8234316        NaN        NaN
+ [43]        NaN        NaN       -Inf        NaN        NaN -6.5895688
+ [49]        NaN        NaN        NaN        NaN        NaN       -Inf
+ [55]        NaN        NaN        NaN       -Inf        NaN -7.5630539
+ [61]        NaN        NaN -0.2616020 -1.6072795        NaN        NaN
+ [67]        NaN        NaN       -Inf       -Inf        NaN        NaN
+ [73]        NaN        NaN -2.1949228        NaN        NaN       -Inf
+ [79]        NaN        NaN        NaN        NaN        NaN -7.4654027
+ [85]        NaN        NaN        NaN -0.6612643        NaN       -Inf
+ [91]        NaN        NaN       -Inf       -Inf        NaN        NaN
+ [97]        NaN        NaN -1.2409998 -1.8234316        NaN        NaN
+[103]        NaN        NaN       -Inf        NaN        NaN -6.5895688
+[109]        NaN        NaN        NaN        NaN        NaN       -Inf
+[115]        NaN        NaN        NaN       -Inf        NaN -7.5630539
+Warning message:
+In pf(c(-1, 0, 0.2, 2), c(-1, 0, 0.1, 0.9, 3), rep(c(-1, 0, 1, 0.1,  :
   NaNs produced
 
-##com.oracle.truffle.r.test.library.stats.TestStatFunctions.testFunctions32#Output.IgnoreWarningContext#
-#set.seed(1); pbeta(c(NA, 0, NaN, 1/0, -1/0), rep(c(1, 0, 0.1), 5), rep(c(1, 0, 0.1), 5))
- [1]  NA   0 NaN   1   0  NA   0 NaN   1   0  NA   0 NaN   1   0
-
-##com.oracle.truffle.r.test.library.stats.TestStatFunctions.testFunctions32#Output.IgnoreWarningContext#
-#set.seed(1); pbeta(rep(c(1, 0, 0.1), 5), c(NA, 0, NaN, 1/0, -1/0), rep(c(1, 0, 0.1), 5))
- [1]  NA   0 NaN   1 NaN  NA   1 NaN   0 NaN  NA   1 NaN   0 NaN
+##com.oracle.truffle.r.test.library.stats.TestStatFunctions.testFunctions32#Output.MayIgnoreWarningContext#
+#set.seed(1); pf(c(NA, 0, NaN, 1/0, -1/0), rep(c(1, 0, 0.1), 5), rep(c(1, 0, 0.1), 5))
+ [1]  NA NaN NaN   1 NaN  NA   0 NaN   1   0  NA   0 NaN NaN   0
 Warning message:
-In pbeta(rep(c(1, 0, 0.1), 5), c(NA, 0, NaN, 1/0, -1/0), rep(c(1,  :
+In pf(c(NA, 0, NaN, 1/0, -1/0), rep(c(1, 0, 0.1), 5), rep(c(1, 0,  :
   NaNs produced
 
-##com.oracle.truffle.r.test.library.stats.TestStatFunctions.testFunctions32#Output.IgnoreWhitespace#
-#set.seed(1); pbeta(rep(c(1, 0, 0.1), 5), rep(c(1, 0, 0.1), 5), c(NA, 0, NaN, 1/0, -1/0))
- [1]  NA   0 NaN   1 NaN  NA   1 NaN   1 NaN  NA   0 NaN   0 NaN
+##com.oracle.truffle.r.test.library.stats.TestStatFunctions.testFunctions32#Output.MayIgnoreWarningContext#
+#set.seed(1); pf(rep(c(1, 0, 0.1), 5), c(NA, 0, NaN, 1/0, -1/0), rep(c(1, 0, 0.1), 5))
+ [1]         NA        NaN        NaN 0.31731051        NaN         NA
+ [7]        NaN        NaN 0.02868263        NaN         NA        NaN
+[13]        NaN        NaN        NaN
 Warning message:
-In pbeta(rep(c(1, 0, 0.1), 5), rep(c(1, 0, 0.1), 5), c(NA, 0, NaN,  :
+In pf(rep(c(1, 0, 0.1), 5), c(NA, 0, NaN, 1/0, -1/0), rep(c(1, 0,  :
   NaNs produced
 
-##com.oracle.truffle.r.test.library.stats.TestStatFunctions.testFunctions32#Output.IgnoreWhitespace#
-#set.seed(1); pcauchy(0, 10, 10, lower.tail=FALSE, log.p=FALSE)
-[1] 0.75
-
-##com.oracle.truffle.r.test.library.stats.TestStatFunctions.testFunctions32#Output.IgnoreWhitespace#
-#set.seed(1); pcauchy(0, 10, 10, lower.tail=FALSE, log.p=TRUE)
-[1] -0.2876821
-
-##com.oracle.truffle.r.test.library.stats.TestStatFunctions.testFunctions32#Output.IgnoreWhitespace#
-#set.seed(1); pcauchy(0, 10, 10, lower.tail=TRUE, log.p=FALSE)
-[1] 0.25
-
-##com.oracle.truffle.r.test.library.stats.TestStatFunctions.testFunctions32#Output.IgnoreWhitespace#
-#set.seed(1); pcauchy(0, 10, 10, lower.tail=TRUE, log.p=TRUE)
-[1] -1.386294
-
-##com.oracle.truffle.r.test.library.stats.TestStatFunctions.testFunctions32#Output.IgnoreWhitespace#
-#set.seed(1); pcauchy(0, c(0.0653, 0.000123, 32e-80, 8833, 79e70, 0, -1), rep(c(0.0653, 0.000123, 32e-80, 8833, 79e70), 7), lower.tail=FALSE, log.p=FALSE)
- [1] 7.500000e-01 7.500000e-01 7.500000e-01 7.500000e-01 7.500000e-01
- [6] 5.000000e-01 3.915212e-05 1.000000e+00 5.000000e-01 5.000000e-01
-[11] 9.999976e-01 1.000000e+00 5.000000e-01 4.999640e-01 5.000000e-01
-[16] 5.005996e-01 5.000000e-01 1.000000e+00 1.000000e+00 5.000000e-01
-[21] 2.075617e-02 9.994004e-01 1.000000e+00 5.000000e-01 5.000000e-01
-[26] 1.000000e+00 5.000000e-01 1.018592e-79 5.000024e-01 5.000000e-01
-[31] 5.000000e-01 1.000000e+00 1.000000e+00 5.000000e-01 5.000000e-01
-
-##com.oracle.truffle.r.test.library.stats.TestStatFunctions.testFunctions32#Output.IgnoreWhitespace#
-#set.seed(1); pcauchy(0, c(0.0653, 0.000123, 32e-80, 8833, 79e70, 0, -1), rep(c(0.0653, 0.000123, 32e-80, 8833, 79e70), 7), lower.tail=FALSE, log.p=TRUE)
- [1]  -2.876821e-01  -2.876821e-01  -2.876821e-01  -2.876821e-01  -2.876821e-01
- [6]  -6.931472e-01  -1.014806e+01  -1.559865e-78  -6.931472e-01  -6.931472e-01
-[11]  -2.353182e-06  -4.955964e-77  -6.931472e-01  -6.932193e-01  -6.931472e-01
-[16]  -6.919488e-01  -6.931472e-01  -1.153166e-83  -3.559027e-69  -6.931472e-01
-[21]  -3.874912e+00  -5.997521e-04  -8.281233e-76  -6.931472e-01  -6.931472e-01
-[26]  -2.631093e-74  -6.931472e-01  -1.818858e+02  -6.931425e-01  -6.931472e-01
-[31]  -6.931472e-01  -4.432482e-09 -1.289357e-151  -6.931472e-01  -6.931472e-01
-
-##com.oracle.truffle.r.test.library.stats.TestStatFunctions.testFunctions32#Output.IgnoreWhitespace#
-#set.seed(1); pcauchy(0, c(0.0653, 0.000123, 32e-80, 8833, 79e70, 0, -1), rep(c(0.0653, 0.000123, 32e-80, 8833, 79e70), 7), lower.tail=TRUE, log.p=FALSE)
- [1]  2.500000e-01  2.500000e-01  2.500000e-01  2.500000e-01  2.500000e-01
- [6]  5.000000e-01  9.999608e-01  1.559865e-78  5.000000e-01  5.000000e-01
-[11]  2.353180e-06  4.955964e-77  5.000000e-01  5.000360e-01  5.000000e-01
-[16]  4.994004e-01  5.000000e-01  1.153166e-83  3.559027e-69  5.000000e-01
-[21]  9.792438e-01  5.995723e-04  8.281233e-76  5.000000e-01  5.000000e-01
-[26]  2.631093e-74  5.000000e-01  1.000000e+00  4.999976e-01  5.000000e-01
-[31]  5.000000e-01  4.432482e-09 1.289357e-151  5.000000e-01  5.000000e-01
-
-##com.oracle.truffle.r.test.library.stats.TestStatFunctions.testFunctions32#Output.IgnoreWhitespace#
-#set.seed(1); pcauchy(0, c(0.0653, 0.000123, 32e-80, 8833, 79e70, 0, -1), rep(c(0.0653, 0.000123, 32e-80, 8833, 79e70), 7), lower.tail=TRUE, log.p=TRUE)
- [1] -1.386294e+00 -1.386294e+00 -1.386294e+00 -1.386294e+00 -1.386294e+00
- [6] -6.931472e-01 -3.915288e-05 -1.791570e+02 -6.931472e-01 -6.931472e-01
-[11] -1.295974e+01 -1.756985e+02 -6.931472e-01 -6.930751e-01 -6.931472e-01
-[16] -6.943470e-01 -6.931472e-01 -1.909721e+02 -1.576089e+02 -6.931472e-01
-[21] -2.097460e-02 -7.419294e+00 -1.728825e+02 -6.931472e-01 -6.931472e-01
-[26] -1.694239e+02 -6.931472e-01 -1.018592e-79 -6.931519e-01 -6.931472e-01
-[31] -6.931472e-01 -1.923431e+01 -3.474362e+02 -6.931472e-01 -6.931472e-01
-
-##com.oracle.truffle.r.test.library.stats.TestStatFunctions.testFunctions32#Output.IgnoreWhitespace#
-#set.seed(1); pcauchy(c(-1, 0, 0.2, 2), c(-1, 0, 0.1, 0.9, 3), rep(c(-1, 0, 1, 0.1, -0.1, 0.0001), 20), lower.tail=FALSE, log.p=FALSE)
-  [1]          NaN          NaN 4.682745e-01 2.885794e-02          NaN
-  [6] 3.183099e-05          NaN          NaN 8.457859e-01 9.893936e-01
- [11]          NaN 1.591549e-05          NaN          NaN 8.908121e-01
- [16] 1.060640e-02          NaN 9.996817e-01          NaN          NaN
- [21] 5.000000e-01 5.000000e-01          NaN 2.893726e-05          NaN
- [26]          NaN 4.371670e-01 1.673771e-02          NaN 9.999894e-01
- [31]          NaN          NaN 7.651462e-01 9.647767e-01          NaN
- [36] 1.061033e-05          NaN          NaN 6.944001e-01 9.682745e-01
- [41]          NaN 5.000000e-01          NaN          NaN 9.220209e-01
- [46] 3.172552e-02          NaN 1.675315e-05          NaN          NaN
- [51] 2.211421e-01 1.590225e-02          NaN 9.999646e-01          NaN
- [56]          NaN 7.500000e-01 7.500000e-01          NaN 9.999682e-01
- [61]          NaN          NaN 4.682745e-01 2.885794e-02          NaN
- [66] 3.183099e-05          NaN          NaN 8.457859e-01 9.893936e-01
- [71]          NaN 1.591549e-05          NaN          NaN 8.908121e-01
- [76] 1.060640e-02          NaN 9.996817e-01          NaN          NaN
- [81] 5.000000e-01 5.000000e-01          NaN 2.893726e-05          NaN
- [86]          NaN 4.371670e-01 1.673771e-02          NaN 9.999894e-01
- [91]          NaN          NaN 7.651462e-01 9.647767e-01          NaN
- [96] 1.061033e-05          NaN          NaN 6.944001e-01 9.682745e-01
-[101]          NaN 5.000000e-01          NaN          NaN 9.220209e-01
-[106] 3.172552e-02          NaN 1.675315e-05          NaN          NaN
-[111] 2.211421e-01 1.590225e-02          NaN 9.999646e-01          NaN
-[116]          NaN 7.500000e-01 7.500000e-01          NaN 9.999682e-01
-Warning message:
-In pcauchy(c(-1, 0, 0.2, 2), c(-1, 0, 0.1, 0.9, 3), rep(c(-1, 0,  :
-  NaNs produced
-
-##com.oracle.truffle.r.test.library.stats.TestStatFunctions.testFunctions32#Output.IgnoreWhitespace#
-#set.seed(1); pcauchy(c(-1, 0, 0.2, 2), c(-1, 0, 0.1, 0.9, 3), rep(c(-1, 0, 1, 0.1, -0.1, 0.0001), 20), lower.tail=FALSE, log.p=TRUE)
-  [1]           NaN           NaN -7.587007e-01 -3.545370e+00           NaN
-  [6] -1.035507e+01           NaN           NaN -1.674890e-01 -1.066305e-02
- [11]           NaN -1.104822e+01           NaN           NaN -1.156218e-01
- [16] -4.546297e+00           NaN -3.183605e-04           NaN           NaN
- [21] -6.931472e-01 -6.931472e-01           NaN -1.045038e+01           NaN
- [26]           NaN -8.274399e-01 -4.090091e+00           NaN -1.061039e-05
- [31]           NaN           NaN -2.676884e-01 -3.585859e-02           NaN
- [36] -1.145368e+01           NaN           NaN -3.647070e-01 -3.223968e-02
- [41]           NaN -6.931472e-01           NaN           NaN -8.118742e-02
- [46] -3.450634e+00           NaN -1.099692e+01           NaN           NaN
- [51] -1.508950e+00 -4.141295e+00           NaN -3.536839e-05           NaN
- [56]           NaN -2.876821e-01 -2.876821e-01           NaN -3.183150e-05
- [61]           NaN           NaN -7.587007e-01 -3.545370e+00           NaN
- [66] -1.035507e+01           NaN           NaN -1.674890e-01 -1.066305e-02
- [71]           NaN -1.104822e+01           NaN           NaN -1.156218e-01
- [76] -4.546297e+00           NaN -3.183605e-04           NaN           NaN
- [81] -6.931472e-01 -6.931472e-01           NaN -1.045038e+01           NaN
- [86]           NaN -8.274399e-01 -4.090091e+00           NaN -1.061039e-05
- [91]           NaN           NaN -2.676884e-01 -3.585859e-02           NaN
- [96] -1.145368e+01           NaN           NaN -3.647070e-01 -3.223968e-02
-[101]           NaN -6.931472e-01           NaN           NaN -8.118742e-02
-[106] -3.450634e+00           NaN -1.099692e+01           NaN           NaN
-[111] -1.508950e+00 -4.141295e+00           NaN -3.536839e-05           NaN
-[116]           NaN -2.876821e-01 -2.876821e-01           NaN -3.183150e-05
-Warning message:
-In pcauchy(c(-1, 0, 0.2, 2), c(-1, 0, 0.1, 0.9, 3), rep(c(-1, 0,  :
-  NaNs produced
-
-##com.oracle.truffle.r.test.library.stats.TestStatFunctions.testFunctions32#Output.IgnoreWhitespace#
-#set.seed(1); pcauchy(c(-1, 0, 0.2, 2), c(-1, 0, 0.1, 0.9, 3), rep(c(-1, 0, 1, 0.1, -0.1, 0.0001), 20), lower.tail=TRUE, log.p=FALSE)
-  [1]          NaN          NaN 5.317255e-01 9.711421e-01          NaN
-  [6] 9.999682e-01          NaN          NaN 1.542141e-01 1.060640e-02
- [11]          NaN 9.999841e-01          NaN          NaN 1.091879e-01
- [16] 9.893936e-01          NaN 3.183098e-04          NaN          NaN
- [21] 5.000000e-01 5.000000e-01          NaN 9.999711e-01          NaN
- [26]          NaN 5.628330e-01 9.832623e-01          NaN 1.061033e-05
- [31]          NaN          NaN 2.348538e-01 3.522329e-02          NaN
- [36] 9.999894e-01          NaN          NaN 3.055999e-01 3.172552e-02
- [41]          NaN 5.000000e-01          NaN          NaN 7.797913e-02
- [46] 9.682745e-01          NaN 9.999832e-01          NaN          NaN
- [51] 7.788579e-01 9.840977e-01          NaN 3.536776e-05          NaN
- [56]          NaN 2.500000e-01 2.500000e-01          NaN 3.183099e-05
- [61]          NaN          NaN 5.317255e-01 9.711421e-01          NaN
- [66] 9.999682e-01          NaN          NaN 1.542141e-01 1.060640e-02
- [71]          NaN 9.999841e-01          NaN          NaN 1.091879e-01
- [76] 9.893936e-01          NaN 3.183098e-04          NaN          NaN
- [81] 5.000000e-01 5.000000e-01          NaN 9.999711e-01          NaN
- [86]          NaN 5.628330e-01 9.832623e-01          NaN 1.061033e-05
- [91]          NaN          NaN 2.348538e-01 3.522329e-02          NaN
- [96] 9.999894e-01          NaN          NaN 3.055999e-01 3.172552e-02
-[101]          NaN 5.000000e-01          NaN          NaN 7.797913e-02
-[106] 9.682745e-01          NaN 9.999832e-01          NaN          NaN
-[111] 7.788579e-01 9.840977e-01          NaN 3.536776e-05          NaN
-[116]          NaN 2.500000e-01 2.500000e-01          NaN 3.183099e-05
-Warning message:
-In pcauchy(c(-1, 0, 0.2, 2), c(-1, 0, 0.1, 0.9, 3), rep(c(-1, 0,  :
-  NaNs produced
-
-##com.oracle.truffle.r.test.library.stats.TestStatFunctions.testFunctions32#Output.IgnoreWhitespace#
-#set.seed(1); pcauchy(c(-1, 0, 0.2, 2), c(-1, 0, 0.1, 0.9, 3), rep(c(-1, 0, 1, 0.1, -0.1, 0.0001), 20), lower.tail=TRUE, log.p=TRUE)
-  [1]           NaN           NaN -6.316279e-01 -2.928252e-02           NaN
-  [6] -3.183150e-05           NaN           NaN -1.869413e+00 -4.546297e+00
- [11]           NaN -1.591562e-05           NaN           NaN -2.214685e+00
- [16] -1.066305e-02           NaN -8.052485e+00           NaN           NaN
- [21] -6.931472e-01 -6.931472e-01           NaN -2.893768e-05           NaN
- [26]           NaN -5.747724e-01 -1.687937e-02           NaN -1.145368e+01
- [31]           NaN           NaN -1.448792e+00 -3.346048e+00           NaN
- [36] -1.061039e-05           NaN           NaN -1.185479e+00 -3.450634e+00
- [41]           NaN -6.931472e-01           NaN           NaN -2.551314e+00
- [46] -3.223968e-02           NaN -1.675329e-05           NaN           NaN
- [51] -2.499266e-01 -1.603005e-02           NaN -1.024971e+01           NaN
- [56]           NaN -1.386294e+00 -1.386294e+00           NaN -1.035507e+01
- [61]           NaN           NaN -6.316279e-01 -2.928252e-02           NaN
- [66] -3.183150e-05           NaN           NaN -1.869413e+00 -4.546297e+00
- [71]           NaN -1.591562e-05           NaN           NaN -2.214685e+00
- [76] -1.066305e-02           NaN -8.052485e+00           NaN           NaN
- [81] -6.931472e-01 -6.931472e-01           NaN -2.893768e-05           NaN
- [86]           NaN -5.747724e-01 -1.687937e-02           NaN -1.145368e+01
- [91]           NaN           NaN -1.448792e+00 -3.346048e+00           NaN
- [96] -1.061039e-05           NaN           NaN -1.185479e+00 -3.450634e+00
-[101]           NaN -6.931472e-01           NaN           NaN -2.551314e+00
-[106] -3.223968e-02           NaN -1.675329e-05           NaN           NaN
-[111] -2.499266e-01 -1.603005e-02           NaN -1.024971e+01           NaN
-[116]           NaN -1.386294e+00 -1.386294e+00           NaN -1.035507e+01
-Warning message:
-In pcauchy(c(-1, 0, 0.2, 2), c(-1, 0, 0.1, 0.9, 3), rep(c(-1, 0,  :
-  NaNs produced
-
-##com.oracle.truffle.r.test.library.stats.TestStatFunctions.testFunctions32#Output.IgnoreWarningContext#
-#set.seed(1); pcauchy(c(NA, 0, NaN, 1/0, -1/0), rep(c(1, 0, 0.1), 5), rep(c(1, 0, 0.1), 5))
- [1]   NA  NaN  NaN 1.00  NaN   NA 0.25  NaN 1.00 0.00   NA 0.25  NaN  NaN 0.00
-Warning message:
-In pcauchy(c(NA, 0, NaN, 1/0, -1/0), rep(c(1, 0, 0.1), 5), rep(c(1,  :
-  NaNs produced
-
-##com.oracle.truffle.r.test.library.stats.TestStatFunctions.testFunctions32#Output.IgnoreWarningContext#
-#set.seed(1); pcauchy(rep(c(1, 0, 0.1), 5), c(NA, 0, NaN, 1/0, -1/0), rep(c(1, 0, 0.1), 5))
- [1]   NA  NaN  NaN 0.00  NaN   NA 0.75  NaN 0.00 1.00   NA 0.75  NaN  NaN 1.00
-Warning message:
-In pcauchy(rep(c(1, 0, 0.1), 5), c(NA, 0, NaN, 1/0, -1/0), rep(c(1,  :
-  NaNs produced
-
-##com.oracle.truffle.r.test.library.stats.TestStatFunctions.testFunctions32#Output.IgnoreWhitespace#
-#set.seed(1); pcauchy(rep(c(1, 0, 0.1), 5), rep(c(1, 0, 0.1), 5), c(NA, 0, NaN, 1/0, -1/0))
- [1]  NA NaN NaN 0.5 NaN  NA NaN NaN 0.5 NaN  NA NaN NaN 0.5 NaN
+##com.oracle.truffle.r.test.library.stats.TestStatFunctions.testFunctions32#Output.MayIgnoreWarningContext#
+#set.seed(1); pf(rep(c(1, 0, 0.1), 5), rep(c(1, 0, 0.1), 5), c(NA, 0, NaN, 1/0, -1/0))
+ [1]        NA       NaN       NaN 0.6826895       NaN        NA       NaN
+ [8]       NaN 0.7879658       NaN        NA       NaN       NaN       NaN
+[15]       NaN
 Warning message:
-In pcauchy(rep(c(1, 0, 0.1), 5), rep(c(1, 0, 0.1), 5), c(NA, 0,  :
+In pf(rep(c(1, 0, 0.1), 5), rep(c(1, 0, 0.1), 5), c(NA, 0, NaN,  :
   NaNs produced
 
-##com.oracle.truffle.r.test.library.stats.TestStatFunctions.testFunctions32#Output.IgnoreWhitespace#
+##com.oracle.truffle.r.test.library.stats.TestStatFunctions.testFunctions32#Output.MayIgnoreWarningContext#
 #set.seed(1); plnorm(0, 10, 10, lower.tail=FALSE, log.p=FALSE)
 [1] 1
 
-##com.oracle.truffle.r.test.library.stats.TestStatFunctions.testFunctions32#Output.IgnoreWhitespace#
+##com.oracle.truffle.r.test.library.stats.TestStatFunctions.testFunctions32#Output.MayIgnoreWarningContext#
 #set.seed(1); plnorm(0, 10, 10, lower.tail=FALSE, log.p=TRUE)
 [1] 0
 
-##com.oracle.truffle.r.test.library.stats.TestStatFunctions.testFunctions32#Output.IgnoreWhitespace#
+##com.oracle.truffle.r.test.library.stats.TestStatFunctions.testFunctions32#Output.MayIgnoreWarningContext#
 #set.seed(1); plnorm(0, 10, 10, lower.tail=TRUE, log.p=FALSE)
 [1] 0
 
-##com.oracle.truffle.r.test.library.stats.TestStatFunctions.testFunctions32#Output.IgnoreWhitespace#
+##com.oracle.truffle.r.test.library.stats.TestStatFunctions.testFunctions32#Output.MayIgnoreWarningContext#
 #set.seed(1); plnorm(0, 10, 10, lower.tail=TRUE, log.p=TRUE)
 [1] -Inf
 
-##com.oracle.truffle.r.test.library.stats.TestStatFunctions.testFunctions32#Output.IgnoreWhitespace#
+##com.oracle.truffle.r.test.library.stats.TestStatFunctions.testFunctions32#Output.MayIgnoreWarningContext#
 #set.seed(1); plnorm(0, c(0.0653, 0.000123, 32e-80, 8833, 79e70, 0, -1), rep(c(0.0653, 0.000123, 32e-80, 8833, 79e70), 7), lower.tail=FALSE, log.p=FALSE)
  [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 1 1 1 1 1 1 1 1 1
 
-##com.oracle.truffle.r.test.library.stats.TestStatFunctions.testFunctions32#Output.IgnoreWhitespace#
+##com.oracle.truffle.r.test.library.stats.TestStatFunctions.testFunctions32#Output.MayIgnoreWarningContext#
 #set.seed(1); plnorm(0, c(0.0653, 0.000123, 32e-80, 8833, 79e70, 0, -1), rep(c(0.0653, 0.000123, 32e-80, 8833, 79e70), 7), lower.tail=FALSE, log.p=TRUE)
  [1] 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
 
-##com.oracle.truffle.r.test.library.stats.TestStatFunctions.testFunctions32#Output.IgnoreWhitespace#
+##com.oracle.truffle.r.test.library.stats.TestStatFunctions.testFunctions32#Output.MayIgnoreWarningContext#
 #set.seed(1); plnorm(0, c(0.0653, 0.000123, 32e-80, 8833, 79e70, 0, -1), rep(c(0.0653, 0.000123, 32e-80, 8833, 79e70), 7), lower.tail=TRUE, log.p=FALSE)
  [1] 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
 
-##com.oracle.truffle.r.test.library.stats.TestStatFunctions.testFunctions32#Output.IgnoreWhitespace#
+##com.oracle.truffle.r.test.library.stats.TestStatFunctions.testFunctions32#Output.MayIgnoreWarningContext#
 #set.seed(1); plnorm(0, c(0.0653, 0.000123, 32e-80, 8833, 79e70, 0, -1), rep(c(0.0653, 0.000123, 32e-80, 8833, 79e70), 7), lower.tail=TRUE, log.p=TRUE)
  [1] -Inf -Inf -Inf -Inf -Inf -Inf -Inf -Inf -Inf -Inf -Inf -Inf -Inf -Inf -Inf
 [16] -Inf -Inf -Inf -Inf -Inf -Inf -Inf -Inf -Inf -Inf -Inf -Inf -Inf -Inf -Inf
 [31] -Inf -Inf -Inf -Inf -Inf
 
-##com.oracle.truffle.r.test.library.stats.TestStatFunctions.testFunctions32#Output.IgnoreWhitespace#
+##com.oracle.truffle.r.test.library.stats.TestStatFunctions.testFunctions32#Output.MayIgnoreWarningContext#
 #set.seed(1); plnorm(c(-1, 0, 0.2, 2), c(-1, 0, 0.1, 0.9, 3), rep(c(-1, 0, 1, 0.1, -0.1, 0.0001), 20), lower.tail=FALSE, log.p=FALSE)
   [1]          NaN 1.000000e+00 9.563151e-01 9.807048e-01          NaN
   [6] 1.000000e+00          NaN 0.000000e+00 1.000000e+00 1.000000e+00
@@ -115522,7 +119524,7 @@ Warning message:
 In plnorm(c(-1, 0, 0.2, 2), c(-1, 0, 0.1, 0.9, 3), rep(c(-1, 0,  :
   NaNs produced
 
-##com.oracle.truffle.r.test.library.stats.TestStatFunctions.testFunctions32#Output.IgnoreWhitespace#
+##com.oracle.truffle.r.test.library.stats.TestStatFunctions.testFunctions32#Output.MayIgnoreWarningContext#
 #set.seed(1); plnorm(c(-1, 0, 0.2, 2), c(-1, 0, 0.1, 0.9, 3), rep(c(-1, 0, 1, 0.1, -0.1, 0.0001), 20), lower.tail=FALSE, log.p=TRUE)
   [1]            NaN   0.000000e+00  -4.466785e-02  -1.948377e-02            NaN
   [6]   0.000000e+00            NaN           -Inf   0.000000e+00   0.000000e+00
@@ -115552,7 +119554,7 @@ Warning message:
 In plnorm(c(-1, 0, 0.2, 2), c(-1, 0, 0.1, 0.9, 3), rep(c(-1, 0,  :
   NaNs produced
 
-##com.oracle.truffle.r.test.library.stats.TestStatFunctions.testFunctions32#Output.IgnoreWhitespace#
+##com.oracle.truffle.r.test.library.stats.TestStatFunctions.testFunctions32#Output.MayIgnoreWarningContext#
 #set.seed(1); plnorm(c(-1, 0, 0.2, 2), c(-1, 0, 0.1, 0.9, 3), rep(c(-1, 0, 1, 0.1, -0.1, 0.0001), 20), lower.tail=TRUE, log.p=FALSE)
   [1]           NaN  0.000000e+00  4.368493e-02  1.929519e-02           NaN
   [6]  0.000000e+00           NaN  1.000000e+00  0.000000e+00  0.000000e+00
@@ -115582,7 +119584,7 @@ Warning message:
 In plnorm(c(-1, 0, 0.2, 2), c(-1, 0, 0.1, 0.9, 3), rep(c(-1, 0,  :
   NaNs produced
 
-##com.oracle.truffle.r.test.library.stats.TestStatFunctions.testFunctions32#Output.IgnoreWhitespace#
+##com.oracle.truffle.r.test.library.stats.TestStatFunctions.testFunctions32#Output.MayIgnoreWarningContext#
 #set.seed(1); plnorm(c(-1, 0, 0.2, 2), c(-1, 0, 0.1, 0.9, 3), rep(c(-1, 0, 1, 0.1, -0.1, 0.0001), 20), lower.tail=TRUE, log.p=TRUE)
   [1]           NaN          -Inf -3.130752e+00 -3.947899e+00           NaN
   [6]          -Inf           NaN  0.000000e+00          -Inf          -Inf
@@ -115612,223 +119614,578 @@ Warning message:
 In plnorm(c(-1, 0, 0.2, 2), c(-1, 0, 0.1, 0.9, 3), rep(c(-1, 0,  :
   NaNs produced
 
-##com.oracle.truffle.r.test.library.stats.TestStatFunctions.testFunctions32#Output.IgnoreWarningContext#
+##com.oracle.truffle.r.test.library.stats.TestStatFunctions.testFunctions32#Output.MayIgnoreWarningContext#
 #set.seed(1); plnorm(c(NA, 0, NaN, 1/0, -1/0), rep(c(1, 0, 0.1), 5), rep(c(1, 0, 0.1), 5))
  [1]  NA   0 NaN   1   0  NA   0 NaN   1   0  NA   0 NaN   1   0
 
-##com.oracle.truffle.r.test.library.stats.TestStatFunctions.testFunctions32#Output.IgnoreWarningContext#
+##com.oracle.truffle.r.test.library.stats.TestStatFunctions.testFunctions32#Output.MayIgnoreWarningContext#
 #set.seed(1); plnorm(rep(c(1, 0, 0.1), 5), c(NA, 0, NaN, 1/0, -1/0), rep(c(1, 0, 0.1), 5))
  [1]            NA  0.000000e+00           NaN  0.000000e+00  0.000000e+00
  [6]            NA  5.000000e-01           NaN  0.000000e+00  1.000000e+00
 [11]            NA 1.284176e-117           NaN  0.000000e+00  1.000000e+00
 
-##com.oracle.truffle.r.test.library.stats.TestStatFunctions.testFunctions32#Output.IgnoreWhitespace#
+##com.oracle.truffle.r.test.library.stats.TestStatFunctions.testFunctions32#Output.MayIgnoreWarningContext#
 #set.seed(1); plnorm(rep(c(1, 0, 0.1), 5), rep(c(1, 0, 0.1), 5), c(NA, 0, NaN, 1/0, -1/0))
  [1]  NA 0.0 NaN 0.5 NaN  NA 0.0 NaN 0.5 NaN  NA 0.0 NaN 0.0 NaN
 Warning message:
 In plnorm(rep(c(1, 0, 0.1), 5), rep(c(1, 0, 0.1), 5), c(NA, 0, NaN,  :
   NaNs produced
 
-##com.oracle.truffle.r.test.library.stats.TestStatFunctions.testFunctions32#Output.IgnoreWhitespace#
-#set.seed(1); qcauchy(0, 10, 10, lower.tail=FALSE, log.p=FALSE)
+##com.oracle.truffle.r.test.library.stats.TestStatFunctions.testFunctions32#Output.MayIgnoreWarningContext#
+#set.seed(1); plogis(0, 10, 10, lower.tail=FALSE, log.p=FALSE)
+[1] 0.7310586
+
+##com.oracle.truffle.r.test.library.stats.TestStatFunctions.testFunctions32#Output.MayIgnoreWarningContext#
+#set.seed(1); plogis(0, 10, 10, lower.tail=FALSE, log.p=TRUE)
+[1] -0.3132617
+
+##com.oracle.truffle.r.test.library.stats.TestStatFunctions.testFunctions32#Output.MayIgnoreWarningContext#
+#set.seed(1); plogis(0, 10, 10, lower.tail=TRUE, log.p=FALSE)
+[1] 0.2689414
+
+##com.oracle.truffle.r.test.library.stats.TestStatFunctions.testFunctions32#Output.MayIgnoreWarningContext#
+#set.seed(1); plogis(0, 10, 10, lower.tail=TRUE, log.p=TRUE)
+[1] -1.313262
+
+##com.oracle.truffle.r.test.library.stats.TestStatFunctions.testFunctions32#Output.MayIgnoreWarningContext#
+#set.seed(1); plogis(0, c(0.0653, 0.000123, 32e-80, 8833, 79e70, 0, -1), rep(c(0.0653, 0.000123, 32e-80, 8833, 79e70), 7), lower.tail=FALSE, log.p=FALSE)
+ [1] 7.310586e-01 7.310586e-01 7.310586e-01 7.310586e-01 7.310586e-01
+ [6] 5.000000e-01 0.000000e+00 1.000000e+00 5.000000e-01 5.000000e-01
+[11] 1.000000e+00 1.000000e+00 5.000000e-01 4.999717e-01 5.000000e-01
+[16] 5.004709e-01 5.000000e-01 1.000000e+00 1.000000e+00 5.000000e-01
+[21] 2.234818e-07 1.000000e+00 1.000000e+00 5.000000e-01 5.000000e-01
+[26] 1.000000e+00 5.000000e-01 0.000000e+00 5.000018e-01 5.000000e-01
+[31] 5.000000e-01 1.000000e+00 1.000000e+00 5.000000e-01 5.000000e-01
+
+##com.oracle.truffle.r.test.library.stats.TestStatFunctions.testFunctions32#Output.MayIgnoreWarningContext#
+#set.seed(1); plogis(0, c(0.0653, 0.000123, 32e-80, 8833, 79e70, 0, -1), rep(c(0.0653, 0.000123, 32e-80, 8833, 79e70), 7), lower.tail=FALSE, log.p=TRUE)
+ [1]  -3.132617e-01  -3.132617e-01  -3.132617e-01  -3.132617e-01  -3.132617e-01
+ [6]  -6.931472e-01  -8.130081e+03   0.000000e+00  -6.931472e-01  -6.931472e-01
+[11]   0.000000e+00   0.000000e+00  -6.931472e-01  -6.932038e-01  -6.931472e-01
+[16]  -6.922058e-01  -6.931472e-01   0.000000e+00   0.000000e+00  -6.931472e-01
+[21]  -1.531394e+01 -2.726033e-231   0.000000e+00  -6.931472e-01  -6.931472e-01
+[26]   0.000000e+00  -6.931472e-01  -3.125000e+78  -6.931435e-01  -6.931472e-01
+[31]  -6.931472e-01   0.000000e+00   0.000000e+00  -6.931472e-01  -6.931472e-01
+
+##com.oracle.truffle.r.test.library.stats.TestStatFunctions.testFunctions32#Output.MayIgnoreWarningContext#
+#set.seed(1); plogis(0, c(0.0653, 0.000123, 32e-80, 8833, 79e70, 0, -1), rep(c(0.0653, 0.000123, 32e-80, 8833, 79e70), 7), lower.tail=TRUE, log.p=FALSE)
+ [1]  2.689414e-01  2.689414e-01  2.689414e-01  2.689414e-01  2.689414e-01
+ [6]  5.000000e-01  1.000000e+00  0.000000e+00  5.000000e-01  5.000000e-01
+[11]  0.000000e+00  0.000000e+00  5.000000e-01  5.000283e-01  5.000000e-01
+[16]  4.995291e-01  5.000000e-01  0.000000e+00  0.000000e+00  5.000000e-01
+[21]  9.999998e-01 2.726033e-231  0.000000e+00  5.000000e-01  5.000000e-01
+[26]  0.000000e+00  5.000000e-01  1.000000e+00  4.999982e-01  5.000000e-01
+[31]  5.000000e-01  0.000000e+00  0.000000e+00  5.000000e-01  5.000000e-01
+
+##com.oracle.truffle.r.test.library.stats.TestStatFunctions.testFunctions32#Output.MayIgnoreWarningContext#
+#set.seed(1); plogis(0, c(0.0653, 0.000123, 32e-80, 8833, 79e70, 0, -1), rep(c(0.0653, 0.000123, 32e-80, 8833, 79e70), 7), lower.tail=TRUE, log.p=TRUE)
+ [1]  -1.313262e+00  -1.313262e+00  -1.313262e+00  -1.313262e+00  -1.313262e+00
+ [6]  -6.931472e-01   0.000000e+00  -2.040625e+77  -6.931472e-01  -6.931472e-01
+[11]  -1.352680e+05  -6.422764e+75  -6.931472e-01  -6.930906e-01  -6.931472e-01
+[16]  -6.940894e-01  -6.931472e-01  -2.760313e+82  -8.943734e+67  -6.931472e-01
+[21]  -2.234818e-07  -5.308943e+02  -3.843750e+74  -6.931472e-01  -6.931472e-01
+[26]  -1.209801e+73  -6.931472e-01   0.000000e+00  -6.931509e-01  -6.931472e-01
+[31]  -6.931472e-01  -7.181301e+07 -2.468750e+150  -6.931472e-01  -6.931472e-01
+
+##com.oracle.truffle.r.test.library.stats.TestStatFunctions.testFunctions32#Output.MayIgnoreWarningContext#
+#set.seed(1); plogis(c(-1, 0, 0.2, 2), c(-1, 0, 0.1, 0.9, 3), rep(c(-1, 0, 1, 0.1, -0.1, 0.0001), 20), lower.tail=FALSE, log.p=FALSE)
+  [1]          NaN          NaN 4.750208e-01 1.670142e-05          NaN
+  [6] 0.000000e+00          NaN          NaN 8.698915e-01 1.000000e+00
+ [11]          NaN 0.000000e+00          NaN          NaN 9.426758e-01
+ [16] 9.357623e-14          NaN 1.000000e+00          NaN          NaN
+ [21] 5.000000e-01 5.000000e-01          NaN 0.000000e+00          NaN
+ [26]          NaN 4.501660e-01 5.602796e-09          NaN 1.000000e+00
+ [31]          NaN          NaN 7.502601e-01 9.998766e-01          NaN
+ [36] 0.000000e+00          NaN          NaN 6.681878e-01 9.999546e-01
+ [41]          NaN 5.000000e-01          NaN          NaN 9.820138e-01
+ [46] 4.539787e-05          NaN 0.000000e+00          NaN          NaN
+ [51] 2.314752e-01 2.061154e-09          NaN 1.000000e+00          NaN
+ [56]          NaN 7.310586e-01 7.310586e-01          NaN 1.000000e+00
+ [61]          NaN          NaN 4.750208e-01 1.670142e-05          NaN
+ [66] 0.000000e+00          NaN          NaN 8.698915e-01 1.000000e+00
+ [71]          NaN 0.000000e+00          NaN          NaN 9.426758e-01
+ [76] 9.357623e-14          NaN 1.000000e+00          NaN          NaN
+ [81] 5.000000e-01 5.000000e-01          NaN 0.000000e+00          NaN
+ [86]          NaN 4.501660e-01 5.602796e-09          NaN 1.000000e+00
+ [91]          NaN          NaN 7.502601e-01 9.998766e-01          NaN
+ [96] 0.000000e+00          NaN          NaN 6.681878e-01 9.999546e-01
+[101]          NaN 5.000000e-01          NaN          NaN 9.820138e-01
+[106] 4.539787e-05          NaN 0.000000e+00          NaN          NaN
+[111] 2.314752e-01 2.061154e-09          NaN 1.000000e+00          NaN
+[116]          NaN 7.310586e-01 7.310586e-01          NaN 1.000000e+00
+Warning message:
+In plogis(c(-1, 0, 0.2, 2), c(-1, 0, 0.1, 0.9, 3), rep(c(-1, 0,  :
+  NaNs produced
+
+##com.oracle.truffle.r.test.library.stats.TestStatFunctions.testFunctions32#Output.MayIgnoreWarningContext#
+#set.seed(1); plogis(c(-1, 0, 0.2, 2), c(-1, 0, 0.1, 0.9, 3), rep(c(-1, 0, 1, 0.1, -0.1, 0.0001), 20), lower.tail=FALSE, log.p=TRUE)
+  [1]           NaN           NaN -7.443967e-01 -1.100002e+01           NaN
+  [6] -1.000000e+04           NaN           NaN -1.393868e-01 -9.357623e-14
+ [11]           NaN -2.000000e+04           NaN           NaN -5.903283e-02
+ [16] -3.000000e+01           NaN  0.000000e+00           NaN           NaN
+ [21] -6.931472e-01 -6.931472e-01           NaN -1.100000e+04           NaN
+ [26]           NaN -7.981389e-01 -1.900000e+01           NaN  0.000000e+00
+ [31]           NaN           NaN -2.873353e-01 -1.234022e-04           NaN
+ [36] -3.000000e+04           NaN           NaN -4.031860e-01 -4.539890e-05
+ [41]           NaN -6.931472e-01           NaN           NaN -1.814993e-02
+ [46] -1.000005e+01           NaN -1.900000e+04           NaN           NaN
+ [51] -1.463282e+00 -2.000000e+01           NaN  0.000000e+00           NaN
+ [56]           NaN -3.132617e-01 -3.132617e-01           NaN  0.000000e+00
+ [61]           NaN           NaN -7.443967e-01 -1.100002e+01           NaN
+ [66] -1.000000e+04           NaN           NaN -1.393868e-01 -9.357623e-14
+ [71]           NaN -2.000000e+04           NaN           NaN -5.903283e-02
+ [76] -3.000000e+01           NaN  0.000000e+00           NaN           NaN
+ [81] -6.931472e-01 -6.931472e-01           NaN -1.100000e+04           NaN
+ [86]           NaN -7.981389e-01 -1.900000e+01           NaN  0.000000e+00
+ [91]           NaN           NaN -2.873353e-01 -1.234022e-04           NaN
+ [96] -3.000000e+04           NaN           NaN -4.031860e-01 -4.539890e-05
+[101]           NaN -6.931472e-01           NaN           NaN -1.814993e-02
+[106] -1.000005e+01           NaN -1.900000e+04           NaN           NaN
+[111] -1.463282e+00 -2.000000e+01           NaN  0.000000e+00           NaN
+[116]           NaN -3.132617e-01 -3.132617e-01           NaN  0.000000e+00
+Warning message:
+In plogis(c(-1, 0, 0.2, 2), c(-1, 0, 0.1, 0.9, 3), rep(c(-1, 0,  :
+  NaNs produced
+
+##com.oracle.truffle.r.test.library.stats.TestStatFunctions.testFunctions32#Output.MayIgnoreWarningContext#
+#set.seed(1); plogis(c(-1, 0, 0.2, 2), c(-1, 0, 0.1, 0.9, 3), rep(c(-1, 0, 1, 0.1, -0.1, 0.0001), 20), lower.tail=TRUE, log.p=FALSE)
+  [1]          NaN          NaN 5.249792e-01 9.999833e-01          NaN
+  [6] 1.000000e+00          NaN          NaN 1.301085e-01 9.357623e-14
+ [11]          NaN 1.000000e+00          NaN          NaN 5.732418e-02
+ [16] 1.000000e+00          NaN 0.000000e+00          NaN          NaN
+ [21] 5.000000e-01 5.000000e-01          NaN 1.000000e+00          NaN
+ [26]          NaN 5.498340e-01 1.000000e+00          NaN 0.000000e+00
+ [31]          NaN          NaN 2.497399e-01 1.233946e-04          NaN
+ [36] 1.000000e+00          NaN          NaN 3.318122e-01 4.539787e-05
+ [41]          NaN 5.000000e-01          NaN          NaN 1.798621e-02
+ [46] 9.999546e-01          NaN 1.000000e+00          NaN          NaN
+ [51] 7.685248e-01 1.000000e+00          NaN 0.000000e+00          NaN
+ [56]          NaN 2.689414e-01 2.689414e-01          NaN 0.000000e+00
+ [61]          NaN          NaN 5.249792e-01 9.999833e-01          NaN
+ [66] 1.000000e+00          NaN          NaN 1.301085e-01 9.357623e-14
+ [71]          NaN 1.000000e+00          NaN          NaN 5.732418e-02
+ [76] 1.000000e+00          NaN 0.000000e+00          NaN          NaN
+ [81] 5.000000e-01 5.000000e-01          NaN 1.000000e+00          NaN
+ [86]          NaN 5.498340e-01 1.000000e+00          NaN 0.000000e+00
+ [91]          NaN          NaN 2.497399e-01 1.233946e-04          NaN
+ [96] 1.000000e+00          NaN          NaN 3.318122e-01 4.539787e-05
+[101]          NaN 5.000000e-01          NaN          NaN 1.798621e-02
+[106] 9.999546e-01          NaN 1.000000e+00          NaN          NaN
+[111] 7.685248e-01 1.000000e+00          NaN 0.000000e+00          NaN
+[116]          NaN 2.689414e-01 2.689414e-01          NaN 0.000000e+00
+Warning message:
+In plogis(c(-1, 0, 0.2, 2), c(-1, 0, 0.1, 0.9, 3), rep(c(-1, 0,  :
+  NaNs produced
+
+##com.oracle.truffle.r.test.library.stats.TestStatFunctions.testFunctions32#Output.MayIgnoreWarningContext#
+#set.seed(1); plogis(c(-1, 0, 0.2, 2), c(-1, 0, 0.1, 0.9, 3), rep(c(-1, 0, 1, 0.1, -0.1, 0.0001), 20), lower.tail=TRUE, log.p=TRUE)
+  [1]           NaN           NaN -6.443967e-01 -1.670156e-05           NaN
+  [6]  0.000000e+00           NaN           NaN -2.039387e+00 -3.000000e+01
+ [11]           NaN  0.000000e+00           NaN           NaN -2.859033e+00
+ [16] -9.357623e-14           NaN -1.000000e+03           NaN           NaN
+ [21] -6.931472e-01 -6.931472e-01           NaN  0.000000e+00           NaN
+ [26]           NaN -5.981389e-01 -5.602796e-09           NaN -3.000000e+04
+ [31]           NaN           NaN -1.387335e+00 -9.000123e+00           NaN
+ [36]  0.000000e+00           NaN           NaN -1.103186e+00 -1.000005e+01
+ [41]           NaN -6.931472e-01           NaN           NaN -4.018150e+00
+ [46] -4.539890e-05           NaN  0.000000e+00           NaN           NaN
+ [51] -2.632825e-01 -2.061154e-09           NaN -9.000000e+03           NaN
+ [56]           NaN -1.313262e+00 -1.313262e+00           NaN -1.000000e+04
+ [61]           NaN           NaN -6.443967e-01 -1.670156e-05           NaN
+ [66]  0.000000e+00           NaN           NaN -2.039387e+00 -3.000000e+01
+ [71]           NaN  0.000000e+00           NaN           NaN -2.859033e+00
+ [76] -9.357623e-14           NaN -1.000000e+03           NaN           NaN
+ [81] -6.931472e-01 -6.931472e-01           NaN  0.000000e+00           NaN
+ [86]           NaN -5.981389e-01 -5.602796e-09           NaN -3.000000e+04
+ [91]           NaN           NaN -1.387335e+00 -9.000123e+00           NaN
+ [96]  0.000000e+00           NaN           NaN -1.103186e+00 -1.000005e+01
+[101]           NaN -6.931472e-01           NaN           NaN -4.018150e+00
+[106] -4.539890e-05           NaN  0.000000e+00           NaN           NaN
+[111] -2.632825e-01 -2.061154e-09           NaN -9.000000e+03           NaN
+[116]           NaN -1.313262e+00 -1.313262e+00           NaN -1.000000e+04
+Warning message:
+In plogis(c(-1, 0, 0.2, 2), c(-1, 0, 0.1, 0.9, 3), rep(c(-1, 0,  :
+  NaNs produced
+
+##com.oracle.truffle.r.test.library.stats.TestStatFunctions.testFunctions32#Output.MayIgnoreWarningContext#
+#set.seed(1); plogis(c(NA, 0, NaN, 1/0, -1/0), rep(c(1, 0, 0.1), 5), rep(c(1, 0, 0.1), 5))
+ [1]        NA       NaN       NaN 1.0000000       NaN        NA 0.2689414
+ [8]       NaN 1.0000000 0.0000000        NA 0.2689414       NaN       NaN
+[15] 0.0000000
+Warning message:
+In plogis(c(NA, 0, NaN, 1/0, -1/0), rep(c(1, 0, 0.1), 5), rep(c(1,  :
+  NaNs produced
+
+##com.oracle.truffle.r.test.library.stats.TestStatFunctions.testFunctions32#Output.MayIgnoreWarningContext#
+#set.seed(1); plogis(rep(c(1, 0, 0.1), 5), c(NA, 0, NaN, 1/0, -1/0), rep(c(1, 0, 0.1), 5))
+ [1]        NA       NaN       NaN 0.0000000       NaN        NA 0.7310586
+ [8]       NaN 0.0000000 1.0000000        NA 0.7310586       NaN       NaN
+[15] 1.0000000
+Warning message:
+In plogis(rep(c(1, 0, 0.1), 5), c(NA, 0, NaN, 1/0, -1/0), rep(c(1,  :
+  NaNs produced
+
+##com.oracle.truffle.r.test.library.stats.TestStatFunctions.testFunctions32#Output.MayIgnoreWarningContext#
+#set.seed(1); plogis(rep(c(1, 0, 0.1), 5), rep(c(1, 0, 0.1), 5), c(NA, 0, NaN, 1/0, -1/0))
+ [1]  NA NaN NaN 0.5 NaN  NA NaN NaN 0.5 NaN  NA NaN NaN 0.5 NaN
+Warning message:
+In plogis(rep(c(1, 0, 0.1), 5), rep(c(1, 0, 0.1), 5), c(NA, 0, NaN,  :
+  NaNs produced
+
+##com.oracle.truffle.r.test.library.stats.TestStatFunctions.testFunctions32#Output.MayIgnoreWarningContext#
+#set.seed(1); qbinom(0, 10, 10, lower.tail=FALSE, log.p=FALSE)
+[1] NaN
+Warning message:
+In qbinom(0, 10, 10, lower.tail = FALSE, log.p = FALSE) : NaNs produced
+
+##com.oracle.truffle.r.test.library.stats.TestStatFunctions.testFunctions32#Output.MayIgnoreWarningContext#
+#set.seed(1); qbinom(0, 10, 10, lower.tail=FALSE, log.p=TRUE)
+[1] NaN
+Warning message:
+In qbinom(0, 10, 10, lower.tail = FALSE, log.p = TRUE) : NaNs produced
+
+##com.oracle.truffle.r.test.library.stats.TestStatFunctions.testFunctions32#Output.MayIgnoreWarningContext#
+#set.seed(1); qbinom(0, 10, 10, lower.tail=TRUE, log.p=FALSE)
+[1] NaN
+Warning message:
+In qbinom(0, 10, 10, lower.tail = TRUE, log.p = FALSE) : NaNs produced
+
+##com.oracle.truffle.r.test.library.stats.TestStatFunctions.testFunctions32#Output.MayIgnoreWarningContext#
+#set.seed(1); qbinom(0, 10, 10, lower.tail=TRUE, log.p=TRUE)
+[1] NaN
+Warning message:
+In qbinom(0, 10, 10, lower.tail = TRUE, log.p = TRUE) : NaNs produced
+
+##com.oracle.truffle.r.test.library.stats.TestStatFunctions.testFunctions32#Output.MayIgnoreWarningContext#
+#set.seed(1); qbinom(0, c(0.0653, 0.000123, 32e-80, 8833, 79e70, 0, -1), rep(c(0.0653, 0.000123, 32e-80, 8833, 79e70), 7), lower.tail=FALSE, log.p=FALSE)
+ [1]       NaN       NaN       NaN       NaN       NaN 0.000e+00       NaN
+ [8]       NaN       NaN       NaN 8.833e+03 7.900e+71 0.000e+00       NaN
+[15]       NaN       NaN       NaN 8.833e+03       NaN       NaN       NaN
+[22]       NaN       NaN       NaN       NaN 7.900e+71 0.000e+00       NaN
+[29]       NaN       NaN       NaN 8.833e+03 7.900e+71       NaN       NaN
+Warning message:
+In qbinom(0, c(0.0653, 0.000123, 3.2e-79, 8833, 7.9e+71, 0, -1),  :
+  NaNs produced
+
+##com.oracle.truffle.r.test.library.stats.TestStatFunctions.testFunctions32#Output.MayIgnoreWarningContext#
+#set.seed(1); qbinom(0, c(0.0653, 0.000123, 32e-80, 8833, 79e70, 0, -1), rep(c(0.0653, 0.000123, 32e-80, 8833, 79e70), 7), lower.tail=FALSE, log.p=TRUE)
+ [1] NaN NaN NaN NaN NaN   0 NaN NaN NaN NaN   0   0   0 NaN NaN NaN NaN   0 NaN
+[20] NaN NaN NaN NaN NaN NaN   0   0 NaN NaN NaN NaN   0   0 NaN NaN
+Warning message:
+In qbinom(0, c(0.0653, 0.000123, 3.2e-79, 8833, 7.9e+71, 0, -1),  :
+  NaNs produced
+
+##com.oracle.truffle.r.test.library.stats.TestStatFunctions.testFunctions32#Output.MayIgnoreWarningContext#
+#set.seed(1); qbinom(0, c(0.0653, 0.000123, 32e-80, 8833, 79e70, 0, -1), rep(c(0.0653, 0.000123, 32e-80, 8833, 79e70), 7), lower.tail=TRUE, log.p=FALSE)
+ [1] NaN NaN NaN NaN NaN   0 NaN NaN NaN NaN   0   0   0 NaN NaN NaN NaN   0 NaN
+[20] NaN NaN NaN NaN NaN NaN   0   0 NaN NaN NaN NaN   0   0 NaN NaN
+Warning message:
+In qbinom(0, c(0.0653, 0.000123, 3.2e-79, 8833, 7.9e+71, 0, -1),  :
+  NaNs produced
+
+##com.oracle.truffle.r.test.library.stats.TestStatFunctions.testFunctions32#Output.MayIgnoreWarningContext#
+#set.seed(1); qbinom(0, c(0.0653, 0.000123, 32e-80, 8833, 79e70, 0, -1), rep(c(0.0653, 0.000123, 32e-80, 8833, 79e70), 7), lower.tail=TRUE, log.p=TRUE)
+ [1]       NaN       NaN       NaN       NaN       NaN 0.000e+00       NaN
+ [8]       NaN       NaN       NaN 8.833e+03 7.900e+71 0.000e+00       NaN
+[15]       NaN       NaN       NaN 8.833e+03       NaN       NaN       NaN
+[22]       NaN       NaN       NaN       NaN 7.900e+71 0.000e+00       NaN
+[29]       NaN       NaN       NaN 8.833e+03 7.900e+71       NaN       NaN
+Warning message:
+In qbinom(0, c(0.0653, 0.000123, 3.2e-79, 8833, 7.9e+71, 0, -1),  :
+  NaNs produced
+
+##com.oracle.truffle.r.test.library.stats.TestStatFunctions.testFunctions32#Output.MayIgnoreWarningContext#
+#set.seed(1); qbinom(c(-1, 0, 0.2, 2), c(-1, 0, 0.1, 0.9, 3), rep(c(-1, 0, 1, 0.1, -0.1, 0.0001), 20), lower.tail=FALSE, log.p=FALSE)
+  [1] NaN   0 NaN NaN NaN NaN NaN NaN NaN   3 NaN NaN NaN NaN   3 NaN NaN NaN
+ [19] NaN NaN NaN   0 NaN NaN NaN NaN   0 NaN NaN   3 NaN NaN NaN NaN NaN NaN
+ [37] NaN NaN NaN NaN NaN   0 NaN NaN NaN NaN NaN NaN NaN   3 NaN NaN NaN NaN
+ [55] NaN NaN NaN NaN NaN NaN NaN   0 NaN NaN NaN NaN NaN NaN NaN   3 NaN NaN
+ [73] NaN NaN   3 NaN NaN NaN NaN NaN NaN   0 NaN NaN NaN NaN   0 NaN NaN   3
+ [91] NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN   0 NaN NaN NaN NaN NaN NaN
+[109] NaN   3 NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN
+Warning message:
+In qbinom(c(-1, 0, 0.2, 2), c(-1, 0, 0.1, 0.9, 3), rep(c(-1, 0,  :
+  NaNs produced
+
+##com.oracle.truffle.r.test.library.stats.TestStatFunctions.testFunctions32#Output.MayIgnoreWarningContext#
+#set.seed(1); qbinom(c(-1, 0, 0.2, 2), c(-1, 0, 0.1, 0.9, 3), rep(c(-1, 0, 1, 0.1, -0.1, 0.0001), 20), lower.tail=FALSE, log.p=TRUE)
+  [1] NaN   0 NaN NaN NaN NaN NaN NaN NaN   0 NaN NaN NaN NaN NaN NaN NaN NaN
+ [19] NaN NaN NaN   0 NaN NaN NaN NaN NaN NaN NaN   0 NaN NaN NaN NaN NaN NaN
+ [37] NaN NaN NaN NaN NaN   0 NaN NaN   3 NaN NaN NaN NaN   0 NaN NaN NaN NaN
+ [55] NaN NaN   0 NaN NaN NaN NaN   0 NaN NaN NaN NaN NaN NaN NaN   0 NaN NaN
+ [73] NaN NaN NaN NaN NaN NaN NaN NaN NaN   0 NaN NaN NaN NaN NaN NaN NaN   0
+ [91] NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN   0 NaN NaN   3 NaN NaN NaN
+[109] NaN   0 NaN NaN NaN NaN NaN NaN   0 NaN NaN NaN
+Warning message:
+In qbinom(c(-1, 0, 0.2, 2), c(-1, 0, 0.1, 0.9, 3), rep(c(-1, 0,  :
+  NaNs produced
+
+##com.oracle.truffle.r.test.library.stats.TestStatFunctions.testFunctions32#Output.MayIgnoreWarningContext#
+#set.seed(1); qbinom(c(-1, 0, 0.2, 2), c(-1, 0, 0.1, 0.9, 3), rep(c(-1, 0, 1, 0.1, -0.1, 0.0001), 20), lower.tail=TRUE, log.p=FALSE)
+  [1] NaN   0 NaN NaN NaN NaN NaN NaN NaN   0 NaN NaN NaN NaN   3 NaN NaN NaN
+ [19] NaN NaN NaN   0 NaN NaN NaN NaN   0 NaN NaN   0 NaN NaN NaN NaN NaN NaN
+ [37] NaN NaN NaN NaN NaN   0 NaN NaN NaN NaN NaN NaN NaN   0 NaN NaN NaN NaN
+ [55] NaN NaN NaN NaN NaN NaN NaN   0 NaN NaN NaN NaN NaN NaN NaN   0 NaN NaN
+ [73] NaN NaN   3 NaN NaN NaN NaN NaN NaN   0 NaN NaN NaN NaN   0 NaN NaN   0
+ [91] NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN   0 NaN NaN NaN NaN NaN NaN
+[109] NaN   0 NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN
+Warning message:
+In qbinom(c(-1, 0, 0.2, 2), c(-1, 0, 0.1, 0.9, 3), rep(c(-1, 0,  :
+  NaNs produced
+
+##com.oracle.truffle.r.test.library.stats.TestStatFunctions.testFunctions32#Output.MayIgnoreWarningContext#
+#set.seed(1); qbinom(c(-1, 0, 0.2, 2), c(-1, 0, 0.1, 0.9, 3), rep(c(-1, 0, 1, 0.1, -0.1, 0.0001), 20), lower.tail=TRUE, log.p=TRUE)
+  [1] NaN   0 NaN NaN NaN NaN NaN NaN NaN   3 NaN NaN NaN NaN NaN NaN NaN NaN
+ [19] NaN NaN NaN   0 NaN NaN NaN NaN NaN NaN NaN   3 NaN NaN NaN NaN NaN NaN
+ [37] NaN NaN NaN NaN NaN   0 NaN NaN   3 NaN NaN NaN NaN   3 NaN NaN NaN NaN
+ [55] NaN NaN   0 NaN NaN NaN NaN   0 NaN NaN NaN NaN NaN NaN NaN   3 NaN NaN
+ [73] NaN NaN NaN NaN NaN NaN NaN NaN NaN   0 NaN NaN NaN NaN NaN NaN NaN   3
+ [91] NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN   0 NaN NaN   3 NaN NaN NaN
+[109] NaN   3 NaN NaN NaN NaN NaN NaN   0 NaN NaN NaN
+Warning message:
+In qbinom(c(-1, 0, 0.2, 2), c(-1, 0, 0.1, 0.9, 3), rep(c(-1, 0,  :
+  NaNs produced
+
+##com.oracle.truffle.r.test.library.stats.TestStatFunctions.testFunctions32#Output.MayIgnoreWarningContext#
+#set.seed(1); qbinom(c(NA, 0, NaN, 1/0, -1/0), rep(c(1, 0, 0.1), 5), rep(c(1, 0, 0.1), 5))
+ [1]  NA   0 NaN NaN NaN  NA   0 NaN NaN NaN  NA NaN NaN NaN NaN
+Warning message:
+In qbinom(c(NA, 0, NaN, 1/0, -1/0), rep(c(1, 0, 0.1), 5), rep(c(1,  :
+  NaNs produced
+
+##com.oracle.truffle.r.test.library.stats.TestStatFunctions.testFunctions32#Output.MayIgnoreWarningContext#
+#set.seed(1); qbinom(rep(c(1, 0, 0.1), 5), c(NA, 0, NaN, 1/0, -1/0), rep(c(1, 0, 0.1), 5))
+ [1]  NA   0 NaN NaN NaN  NA   0 NaN NaN NaN  NA   0 NaN NaN NaN
+Warning message:
+In qbinom(rep(c(1, 0, 0.1), 5), c(NA, 0, NaN, 1/0, -1/0), rep(c(1,  :
+  NaNs produced
+
+##com.oracle.truffle.r.test.library.stats.TestStatFunctions.testFunctions32#Output.MayIgnoreWarningContext#
+#set.seed(1); qbinom(rep(c(1, 0, 0.1), 5), rep(c(1, 0, 0.1), 5), c(NA, 0, NaN, 1/0, -1/0))
+ [1]  NA   0 NaN NaN NaN  NA   1 NaN NaN NaN  NA NaN NaN NaN NaN
+Warning message:
+In qbinom(rep(c(1, 0, 0.1), 5), rep(c(1, 0, 0.1), 5), c(NA, 0, NaN,  :
+  NaNs produced
+
+##com.oracle.truffle.r.test.library.stats.TestStatFunctions.testFunctions32#Output.MayIgnoreWarningContext#
+#set.seed(1); qf(0, 10, 10, lower.tail=FALSE, log.p=FALSE)
 [1] Inf
 
-##com.oracle.truffle.r.test.library.stats.TestStatFunctions.testFunctions32#Output.IgnoreWhitespace#
-#set.seed(1); qcauchy(0, 10, 10, lower.tail=FALSE, log.p=TRUE)
-[1] -Inf
+##com.oracle.truffle.r.test.library.stats.TestStatFunctions.testFunctions32#Output.MayIgnoreWarningContext#
+#set.seed(1); qf(0, 10, 10, lower.tail=FALSE, log.p=TRUE)
+[1] 0
 
-##com.oracle.truffle.r.test.library.stats.TestStatFunctions.testFunctions32#Output.IgnoreWhitespace#
-#set.seed(1); qcauchy(0, 10, 10, lower.tail=TRUE, log.p=FALSE)
-[1] -Inf
+##com.oracle.truffle.r.test.library.stats.TestStatFunctions.testFunctions32#Output.MayIgnoreWarningContext#
+#set.seed(1); qf(0, 10, 10, lower.tail=TRUE, log.p=FALSE)
+[1] 0
 
-##com.oracle.truffle.r.test.library.stats.TestStatFunctions.testFunctions32#Output.IgnoreWhitespace#
-#set.seed(1); qcauchy(0, 10, 10, lower.tail=TRUE, log.p=TRUE)
+##com.oracle.truffle.r.test.library.stats.TestStatFunctions.testFunctions32#Output.MayIgnoreWarningContext#
+#set.seed(1); qf(0, 10, 10, lower.tail=TRUE, log.p=TRUE)
 [1] Inf
 
-##com.oracle.truffle.r.test.library.stats.TestStatFunctions.testFunctions32#Output.IgnoreWhitespace#
-#set.seed(1); qcauchy(0, c(0.0653, 0.000123, 32e-80, 8833, 79e70, 0, -1), rep(c(0.0653, 0.000123, 32e-80, 8833, 79e70), 7), lower.tail=FALSE, log.p=FALSE)
- [1] Inf Inf Inf Inf Inf Inf Inf Inf Inf Inf Inf Inf Inf Inf Inf Inf Inf Inf Inf
-[20] Inf Inf Inf Inf Inf Inf Inf Inf Inf Inf Inf Inf Inf Inf Inf Inf
+##com.oracle.truffle.r.test.library.stats.TestStatFunctions.testFunctions32#Output.MayIgnoreWarningContext#
+#set.seed(1); qf(0, c(0.0653, 0.000123, 32e-80, 8833, 79e70, 0, -1), rep(c(0.0653, 0.000123, 32e-80, 8833, 79e70), 7), lower.tail=FALSE, log.p=FALSE)
+ [1] Inf Inf Inf Inf Inf NaN NaN Inf Inf Inf Inf Inf NaN NaN Inf Inf Inf Inf Inf
+[20] NaN NaN Inf Inf Inf Inf Inf NaN NaN Inf Inf Inf Inf Inf NaN NaN
+Warning message:
+In qf(0, c(0.0653, 0.000123, 3.2e-79, 8833, 7.9e+71, 0, -1), rep(c(0.0653,  :
+  NaNs produced
 
-##com.oracle.truffle.r.test.library.stats.TestStatFunctions.testFunctions32#Output.IgnoreWhitespace#
-#set.seed(1); qcauchy(0, c(0.0653, 0.000123, 32e-80, 8833, 79e70, 0, -1), rep(c(0.0653, 0.000123, 32e-80, 8833, 79e70), 7), lower.tail=FALSE, log.p=TRUE)
- [1] -Inf -Inf -Inf -Inf -Inf -Inf -Inf -Inf -Inf -Inf -Inf -Inf -Inf -Inf -Inf
-[16] -Inf -Inf -Inf -Inf -Inf -Inf -Inf -Inf -Inf -Inf -Inf -Inf -Inf -Inf -Inf
-[31] -Inf -Inf -Inf -Inf -Inf
+##com.oracle.truffle.r.test.library.stats.TestStatFunctions.testFunctions32#Output.MayIgnoreWarningContext#
+#set.seed(1); qf(0, c(0.0653, 0.000123, 32e-80, 8833, 79e70, 0, -1), rep(c(0.0653, 0.000123, 32e-80, 8833, 79e70), 7), lower.tail=FALSE, log.p=TRUE)
+ [1]   0   0   0   0   0 NaN NaN   0   0   0   0   0 NaN NaN   0   0   0   0   0
+[20] NaN NaN   0   0   0   0   0 NaN NaN   0   0   0   0   0 NaN NaN
+Warning message:
+In qf(0, c(0.0653, 0.000123, 3.2e-79, 8833, 7.9e+71, 0, -1), rep(c(0.0653,  :
+  NaNs produced
 
-##com.oracle.truffle.r.test.library.stats.TestStatFunctions.testFunctions32#Output.IgnoreWhitespace#
-#set.seed(1); qcauchy(0, c(0.0653, 0.000123, 32e-80, 8833, 79e70, 0, -1), rep(c(0.0653, 0.000123, 32e-80, 8833, 79e70), 7), lower.tail=TRUE, log.p=FALSE)
- [1] -Inf -Inf -Inf -Inf -Inf -Inf -Inf -Inf -Inf -Inf -Inf -Inf -Inf -Inf -Inf
-[16] -Inf -Inf -Inf -Inf -Inf -Inf -Inf -Inf -Inf -Inf -Inf -Inf -Inf -Inf -Inf
-[31] -Inf -Inf -Inf -Inf -Inf
+##com.oracle.truffle.r.test.library.stats.TestStatFunctions.testFunctions32#Output.MayIgnoreWarningContext#
+#set.seed(1); qf(0, c(0.0653, 0.000123, 32e-80, 8833, 79e70, 0, -1), rep(c(0.0653, 0.000123, 32e-80, 8833, 79e70), 7), lower.tail=TRUE, log.p=FALSE)
+ [1]   0   0   0   0   0 NaN NaN   0   0   0   0   0 NaN NaN   0   0   0   0   0
+[20] NaN NaN   0   0   0   0   0 NaN NaN   0   0   0   0   0 NaN NaN
+Warning message:
+In qf(0, c(0.0653, 0.000123, 3.2e-79, 8833, 7.9e+71, 0, -1), rep(c(0.0653,  :
+  NaNs produced
 
-##com.oracle.truffle.r.test.library.stats.TestStatFunctions.testFunctions32#Output.IgnoreWhitespace#
-#set.seed(1); qcauchy(0, c(0.0653, 0.000123, 32e-80, 8833, 79e70, 0, -1), rep(c(0.0653, 0.000123, 32e-80, 8833, 79e70), 7), lower.tail=TRUE, log.p=TRUE)
- [1] Inf Inf Inf Inf Inf Inf Inf Inf Inf Inf Inf Inf Inf Inf Inf Inf Inf Inf Inf
-[20] Inf Inf Inf Inf Inf Inf Inf Inf Inf Inf Inf Inf Inf Inf Inf Inf
+##com.oracle.truffle.r.test.library.stats.TestStatFunctions.testFunctions32#Output.MayIgnoreWarningContext#
+#set.seed(1); qf(0, c(0.0653, 0.000123, 32e-80, 8833, 79e70, 0, -1), rep(c(0.0653, 0.000123, 32e-80, 8833, 79e70), 7), lower.tail=TRUE, log.p=TRUE)
+ [1] Inf Inf Inf Inf Inf NaN NaN Inf Inf Inf Inf Inf NaN NaN Inf Inf Inf Inf Inf
+[20] NaN NaN Inf Inf Inf Inf Inf NaN NaN Inf Inf Inf Inf Inf NaN NaN
+Warning message:
+In qf(0, c(0.0653, 0.000123, 3.2e-79, 8833, 7.9e+71, 0, -1), rep(c(0.0653,  :
+  NaNs produced
 
-##com.oracle.truffle.r.test.library.stats.TestStatFunctions.testFunctions32#Output.IgnoreWhitespace#
-#set.seed(1); qcauchy(c(-1, 0, 0.2, 2), c(-1, 0, 0.1, 0.9, 3), rep(c(-1, 0, 1, 0.1, -0.1, 0.0001), 20), lower.tail=FALSE, log.p=FALSE)
-  [1]        NaN  0.0000000  1.4763819        NaN        NaN        Inf
+##com.oracle.truffle.r.test.library.stats.TestStatFunctions.testFunctions32#Output.MayIgnoreWarningContext#
+#set.seed(1); qf(c(-1, 0, 0.2, 2), c(-1, 0, 0.1, 0.9, 3), rep(c(-1, 0, 1, 0.1, -0.1, 0.0001), 20), lower.tail=FALSE, log.p=FALSE)
+  [1]        NaN        NaN  0.4368535        NaN        NaN        NaN
   [7]        NaN        NaN        NaN        Inf        NaN        NaN
- [13]        NaN  0.9000000  4.3763819        NaN        NaN        Inf
- [19]        NaN        NaN        NaN        Inf        NaN        NaN
- [25]        NaN -1.0000000  1.3763819        NaN        NaN        Inf
+ [13]        NaN        NaN 13.0639281        NaN        NaN        Inf
+ [19]        NaN        NaN        NaN        NaN        NaN        NaN
+ [25]        NaN        NaN        NaN        NaN        NaN        Inf
  [31]        NaN        NaN        NaN        Inf        NaN        NaN
- [37]        NaN  0.1000000  2.2763819        NaN        NaN        Inf
- [43]        NaN        NaN        NaN        Inf        NaN        NaN
- [49]        NaN  3.0000000  0.3763819        NaN        NaN        Inf
+ [37]        NaN        NaN  9.0192419        NaN        NaN        NaN
+ [43]        NaN        NaN        NaN        NaN        NaN        NaN
+ [49]        NaN        NaN        NaN        NaN        NaN        Inf
  [55]        NaN        NaN        NaN        Inf        NaN        NaN
- [61]        NaN  0.0000000  1.4763819        NaN        NaN        Inf
+ [61]        NaN        NaN  0.4368535        NaN        NaN        NaN
  [67]        NaN        NaN        NaN        Inf        NaN        NaN
- [73]        NaN  0.9000000  4.3763819        NaN        NaN        Inf
- [79]        NaN        NaN        NaN        Inf        NaN        NaN
- [85]        NaN -1.0000000  1.3763819        NaN        NaN        Inf
+ [73]        NaN        NaN 13.0639281        NaN        NaN        Inf
+ [79]        NaN        NaN        NaN        NaN        NaN        NaN
+ [85]        NaN        NaN        NaN        NaN        NaN        Inf
  [91]        NaN        NaN        NaN        Inf        NaN        NaN
- [97]        NaN  0.1000000  2.2763819        NaN        NaN        Inf
-[103]        NaN        NaN        NaN        Inf        NaN        NaN
-[109]        NaN  3.0000000  0.3763819        NaN        NaN        Inf
+ [97]        NaN        NaN  9.0192419        NaN        NaN        NaN
+[103]        NaN        NaN        NaN        NaN        NaN        NaN
+[109]        NaN        NaN        NaN        NaN        NaN        Inf
 [115]        NaN        NaN        NaN        Inf        NaN        NaN
 Warning message:
-In qcauchy(c(-1, 0, 0.2, 2), c(-1, 0, 0.1, 0.9, 3), rep(c(-1, 0,  :
+In qf(c(-1, 0, 0.2, 2), c(-1, 0, 0.1, 0.9, 3), rep(c(-1, 0, 1, 0.1,  :
   NaNs produced
 
-##com.oracle.truffle.r.test.library.stats.TestStatFunctions.testFunctions32#Output.IgnoreWhitespace#
-#set.seed(1); qcauchy(c(-1, 0, 0.2, 2), c(-1, 0, 0.1, 0.9, 3), rep(c(-1, 0, 1, 0.1, -0.1, 0.0001), 20), lower.tail=FALSE, log.p=TRUE)
-  [1]        NaN  0.0000000        NaN        NaN        NaN       -Inf
-  [7]        NaN        NaN  1.3406711       -Inf        NaN        NaN
- [13]        NaN  0.9000000        NaN        NaN        NaN       -Inf
- [19]        NaN        NaN -0.5593289       -Inf        NaN        NaN
- [25]        NaN -1.0000000        NaN        NaN        NaN       -Inf
- [31]        NaN        NaN  0.5406711       -Inf        NaN        NaN
- [37]        NaN  0.1000000        NaN        NaN        NaN       -Inf
- [43]        NaN        NaN  3.4406711       -Inf        NaN        NaN
- [49]        NaN  3.0000000        NaN        NaN        NaN       -Inf
- [55]        NaN        NaN  0.4406711       -Inf        NaN        NaN
- [61]        NaN  0.0000000        NaN        NaN        NaN       -Inf
- [67]        NaN        NaN  1.3406711       -Inf        NaN        NaN
- [73]        NaN  0.9000000        NaN        NaN        NaN       -Inf
- [79]        NaN        NaN -0.5593289       -Inf        NaN        NaN
- [85]        NaN -1.0000000        NaN        NaN        NaN       -Inf
- [91]        NaN        NaN  0.5406711       -Inf        NaN        NaN
- [97]        NaN  0.1000000        NaN        NaN        NaN       -Inf
-[103]        NaN        NaN  3.4406711       -Inf        NaN        NaN
-[109]        NaN  3.0000000        NaN        NaN        NaN       -Inf
-[115]        NaN        NaN  0.4406711       -Inf        NaN        NaN
-Warning message:
-In qcauchy(c(-1, 0, 0.2, 2), c(-1, 0, 0.1, 0.9, 3), rep(c(-1, 0,  :
+##com.oracle.truffle.r.test.library.stats.TestStatFunctions.testFunctions32#Output.MayIgnoreWarningContext#
+#set.seed(1); qf(c(-1, 0, 0.2, 2), c(-1, 0, 0.1, 0.9, 3), rep(c(-1, 0, 1, 0.1, -0.1, 0.0001), 20), lower.tail=FALSE, log.p=TRUE)
+  [1]        NaN        NaN        NaN        NaN        NaN        NaN
+  [7]        NaN        NaN 2.19885391 0.00000000        NaN        NaN
+ [13]        NaN        NaN        NaN        NaN        NaN 0.00000000
+ [19]        NaN        NaN        NaN        NaN        NaN        NaN
+ [25]        NaN        NaN        NaN        NaN        NaN 0.00000000
+ [31]        NaN        NaN 0.00384456 0.00000000        NaN        NaN
+ [37]        NaN        NaN        NaN        NaN        NaN        NaN
+ [43]        NaN        NaN 3.54447244        NaN        NaN        NaN
+ [49]        NaN        NaN        NaN        NaN        NaN 0.00000000
+ [55]        NaN        NaN        NaN 0.00000000        NaN        NaN
+ [61]        NaN        NaN        NaN        NaN        NaN        NaN
+ [67]        NaN        NaN 2.19885391 0.00000000        NaN        NaN
+ [73]        NaN        NaN        NaN        NaN        NaN 0.00000000
+ [79]        NaN        NaN        NaN        NaN        NaN        NaN
+ [85]        NaN        NaN        NaN        NaN        NaN 0.00000000
+ [91]        NaN        NaN 0.00384456 0.00000000        NaN        NaN
+ [97]        NaN        NaN        NaN        NaN        NaN        NaN
+[103]        NaN        NaN 3.54447244        NaN        NaN        NaN
+[109]        NaN        NaN        NaN        NaN        NaN 0.00000000
+[115]        NaN        NaN        NaN 0.00000000        NaN        NaN
+Warning message:
+In qf(c(-1, 0, 0.2, 2), c(-1, 0, 0.1, 0.9, 3), rep(c(-1, 0, 1, 0.1,  :
   NaNs produced
 
-##com.oracle.truffle.r.test.library.stats.TestStatFunctions.testFunctions32#Output.IgnoreWhitespace#
-#set.seed(1); qcauchy(c(-1, 0, 0.2, 2), c(-1, 0, 0.1, 0.9, 3), rep(c(-1, 0, 1, 0.1, -0.1, 0.0001), 20), lower.tail=TRUE, log.p=FALSE)
-  [1]        NaN  0.0000000 -1.2763819        NaN        NaN       -Inf
-  [7]        NaN        NaN        NaN       -Inf        NaN        NaN
- [13]        NaN  0.9000000  1.6236181        NaN        NaN       -Inf
- [19]        NaN        NaN        NaN       -Inf        NaN        NaN
- [25]        NaN -1.0000000 -1.3763819        NaN        NaN       -Inf
- [31]        NaN        NaN        NaN       -Inf        NaN        NaN
- [37]        NaN  0.1000000 -0.4763819        NaN        NaN       -Inf
- [43]        NaN        NaN        NaN       -Inf        NaN        NaN
- [49]        NaN  3.0000000 -2.3763819        NaN        NaN       -Inf
- [55]        NaN        NaN        NaN       -Inf        NaN        NaN
- [61]        NaN  0.0000000 -1.2763819        NaN        NaN       -Inf
- [67]        NaN        NaN        NaN       -Inf        NaN        NaN
- [73]        NaN  0.9000000  1.6236181        NaN        NaN       -Inf
- [79]        NaN        NaN        NaN       -Inf        NaN        NaN
- [85]        NaN -1.0000000 -1.3763819        NaN        NaN       -Inf
- [91]        NaN        NaN        NaN       -Inf        NaN        NaN
- [97]        NaN  0.1000000 -0.4763819        NaN        NaN       -Inf
-[103]        NaN        NaN        NaN       -Inf        NaN        NaN
-[109]        NaN  3.0000000 -2.3763819        NaN        NaN       -Inf
-[115]        NaN        NaN        NaN       -Inf        NaN        NaN
-Warning message:
-In qcauchy(c(-1, 0, 0.2, 2), c(-1, 0, 0.1, 0.9, 3), rep(c(-1, 0,  :
+##com.oracle.truffle.r.test.library.stats.TestStatFunctions.testFunctions32#Output.MayIgnoreWarningContext#
+#set.seed(1); qf(c(-1, 0, 0.2, 2), c(-1, 0, 0.1, 0.9, 3), rep(c(-1, 0, 1, 0.1, -0.1, 0.0001), 20), lower.tail=TRUE, log.p=FALSE)
+  [1]          NaN          NaN 3.885781e-13          NaN          NaN
+  [6]          NaN          NaN          NaN          NaN 0.000000e+00
+ [11]          NaN          NaN          NaN          NaN 3.728274e-01
+ [16]          NaN          NaN 0.000000e+00          NaN          NaN
+ [21]          NaN          NaN          NaN          NaN          NaN
+ [26]          NaN          NaN          NaN          NaN 0.000000e+00
+ [31]          NaN          NaN          NaN 0.000000e+00          NaN
+ [36]          NaN          NaN          NaN 8.286649e-02          NaN
+ [41]          NaN          NaN          NaN          NaN          NaN
+ [46]          NaN          NaN          NaN          NaN          NaN
+ [51]          NaN          NaN          NaN 0.000000e+00          NaN
+ [56]          NaN          NaN 0.000000e+00          NaN          NaN
+ [61]          NaN          NaN 3.885781e-13          NaN          NaN
+ [66]          NaN          NaN          NaN          NaN 0.000000e+00
+ [71]          NaN          NaN          NaN          NaN 3.728274e-01
+ [76]          NaN          NaN 0.000000e+00          NaN          NaN
+ [81]          NaN          NaN          NaN          NaN          NaN
+ [86]          NaN          NaN          NaN          NaN 0.000000e+00
+ [91]          NaN          NaN          NaN 0.000000e+00          NaN
+ [96]          NaN          NaN          NaN 8.286649e-02          NaN
+[101]          NaN          NaN          NaN          NaN          NaN
+[106]          NaN          NaN          NaN          NaN          NaN
+[111]          NaN          NaN          NaN 0.000000e+00          NaN
+[116]          NaN          NaN 0.000000e+00          NaN          NaN
+Warning message:
+In qf(c(-1, 0, 0.2, 2), c(-1, 0, 0.1, 0.9, 3), rep(c(-1, 0, 1, 0.1,  :
   NaNs produced
 
-##com.oracle.truffle.r.test.library.stats.TestStatFunctions.testFunctions32#Output.IgnoreWhitespace#
-#set.seed(1); qcauchy(c(-1, 0, 0.2, 2), c(-1, 0, 0.1, 0.9, 3), rep(c(-1, 0, 1, 0.1, -0.1, 0.0001), 20), lower.tail=TRUE, log.p=TRUE)
-  [1]        NaN  0.0000000        NaN        NaN        NaN        Inf
-  [7]        NaN        NaN  0.4593289        Inf        NaN        NaN
- [13]        NaN  0.9000000        NaN        NaN        NaN        Inf
- [19]        NaN        NaN -1.4406711        Inf        NaN        NaN
- [25]        NaN -1.0000000        NaN        NaN        NaN        Inf
- [31]        NaN        NaN -0.3406711        Inf        NaN        NaN
- [37]        NaN  0.1000000        NaN        NaN        NaN        Inf
- [43]        NaN        NaN  2.5593289        Inf        NaN        NaN
- [49]        NaN  3.0000000        NaN        NaN        NaN        Inf
- [55]        NaN        NaN -0.4406711        Inf        NaN        NaN
- [61]        NaN  0.0000000        NaN        NaN        NaN        Inf
- [67]        NaN        NaN  0.4593289        Inf        NaN        NaN
- [73]        NaN  0.9000000        NaN        NaN        NaN        Inf
- [79]        NaN        NaN -1.4406711        Inf        NaN        NaN
- [85]        NaN -1.0000000        NaN        NaN        NaN        Inf
- [91]        NaN        NaN -0.3406711        Inf        NaN        NaN
- [97]        NaN  0.1000000        NaN        NaN        NaN        Inf
-[103]        NaN        NaN  2.5593289        Inf        NaN        NaN
-[109]        NaN  3.0000000        NaN        NaN        NaN        Inf
-[115]        NaN        NaN -0.4406711        Inf        NaN        NaN
-Warning message:
-In qcauchy(c(-1, 0, 0.2, 2), c(-1, 0, 0.1, 0.9, 3), rep(c(-1, 0,  :
+##com.oracle.truffle.r.test.library.stats.TestStatFunctions.testFunctions32#Output.MayIgnoreWarningContext#
+#set.seed(1); qf(c(-1, 0, 0.2, 2), c(-1, 0, 0.1, 0.9, 3), rep(c(-1, 0, 1, 0.1, -0.1, 0.0001), 20), lower.tail=TRUE, log.p=TRUE)
+  [1]          NaN          NaN          NaN          NaN          NaN
+  [6]          NaN          NaN          NaN 3.712400e-01          Inf
+ [11]          NaN          NaN          NaN          NaN          NaN
+ [16]          NaN          NaN          Inf          NaN          NaN
+ [21]          NaN          NaN          NaN          NaN          NaN
+ [26]          NaN          NaN          NaN          NaN          Inf
+ [31]          NaN          NaN 7.636093e-08          Inf          NaN
+ [36]          NaN          NaN          NaN          NaN          NaN
+ [41]          NaN          NaN          NaN          NaN 8.941077e-01
+ [46]          NaN          NaN          NaN          NaN          NaN
+ [51]          NaN          NaN          NaN          Inf          NaN
+ [56]          NaN          NaN          Inf          NaN          NaN
+ [61]          NaN          NaN          NaN          NaN          NaN
+ [66]          NaN          NaN          NaN 3.712400e-01          Inf
+ [71]          NaN          NaN          NaN          NaN          NaN
+ [76]          NaN          NaN          Inf          NaN          NaN
+ [81]          NaN          NaN          NaN          NaN          NaN
+ [86]          NaN          NaN          NaN          NaN          Inf
+ [91]          NaN          NaN 7.636093e-08          Inf          NaN
+ [96]          NaN          NaN          NaN          NaN          NaN
+[101]          NaN          NaN          NaN          NaN 8.941077e-01
+[106]          NaN          NaN          NaN          NaN          NaN
+[111]          NaN          NaN          NaN          Inf          NaN
+[116]          NaN          NaN          Inf          NaN          NaN
+Warning message:
+In qf(c(-1, 0, 0.2, 2), c(-1, 0, 0.1, 0.9, 3), rep(c(-1, 0, 1, 0.1,  :
   NaNs produced
 
-##com.oracle.truffle.r.test.library.stats.TestStatFunctions.testFunctions32#Output.IgnoreWarningContext#
-#set.seed(1); qcauchy(c(NA, 0, NaN, 1/0, -1/0), rep(c(1, 0, 0.1), 5), rep(c(1, 0, 0.1), 5))
- [1]   NA    0  NaN  NaN  NaN   NA -Inf  NaN  NaN  NaN   NA -Inf  NaN  NaN  NaN
+##com.oracle.truffle.r.test.library.stats.TestStatFunctions.testFunctions32#Output.MayIgnoreWarningContext#
+#set.seed(1); qf(c(NA, 0, NaN, 1/0, -1/0), rep(c(1, 0, 0.1), 5), rep(c(1, 0, 0.1), 5))
+ [1]  NA NaN NaN NaN NaN  NA   0 NaN NaN NaN  NA   0 NaN NaN NaN
 Warning message:
-In qcauchy(c(NA, 0, NaN, 1/0, -1/0), rep(c(1, 0, 0.1), 5), rep(c(1,  :
+In qf(c(NA, 0, NaN, 1/0, -1/0), rep(c(1, 0, 0.1), 5), rep(c(1, 0,  :
   NaNs produced
 
-##com.oracle.truffle.r.test.library.stats.TestStatFunctions.testFunctions32#Output.IgnoreWarningContext#
-#set.seed(1); qcauchy(rep(c(1, 0, 0.1), 5), c(NA, 0, NaN, 1/0, -1/0), rep(c(1, 0, 0.1), 5))
- [1]         NA  0.0000000        NaN        Inf       -Inf         NA
- [7]        Inf        NaN        Inf        NaN         NA -0.3077684
-[13]        NaN        Inf       -Inf
+##com.oracle.truffle.r.test.library.stats.TestStatFunctions.testFunctions32#Output.MayIgnoreWarningContext#
+#set.seed(1); qf(rep(c(1, 0, 0.1), 5), c(NA, 0, NaN, 1/0, -1/0), rep(c(1, 0, 0.1), 5))
+ [1]       NA      NaN      NaN      Inf      NaN       NA      NaN      NaN
+ [9] 0.655161      NaN       NA      NaN      NaN      NaN      NaN
 Warning message:
-In qcauchy(rep(c(1, 0, 0.1), 5), c(NA, 0, NaN, 1/0, -1/0), rep(c(1,  :
+In qf(rep(c(1, 0, 0.1), 5), c(NA, 0, NaN, 1/0, -1/0), rep(c(1, 0,  :
   NaNs produced
 
-##com.oracle.truffle.r.test.library.stats.TestStatFunctions.testFunctions32#Output.IgnoreWhitespace#
-#set.seed(1); qcauchy(rep(c(1, 0, 0.1), 5), rep(c(1, 0, 0.1), 5), c(NA, 0, NaN, 1/0, -1/0))
- [1]  NA 0.0 NaN NaN NaN  NA 1.0 NaN NaN NaN  NA 0.1 NaN NaN NaN
+##com.oracle.truffle.r.test.library.stats.TestStatFunctions.testFunctions32#Output.MayIgnoreWarningContext#
+#set.seed(1); qf(rep(c(1, 0, 0.1), 5), rep(c(1, 0, 0.1), 5), c(NA, 0, NaN, 1/0, -1/0))
+ [1]           NA          NaN          NaN          Inf          NaN
+ [6]           NA          NaN          NaN 1.168926e-19          NaN
+[11]           NA          NaN          NaN          NaN          NaN
 Warning message:
-In qcauchy(rep(c(1, 0, 0.1), 5), rep(c(1, 0, 0.1), 5), c(NA, 0,  :
+In qf(rep(c(1, 0, 0.1), 5), rep(c(1, 0, 0.1), 5), c(NA, 0, NaN,  :
   NaNs produced
 
-##com.oracle.truffle.r.test.library.stats.TestStatFunctions.testFunctions32#Output.IgnoreWhitespace#
+##com.oracle.truffle.r.test.library.stats.TestStatFunctions.testFunctions32#Output.MayIgnoreWarningContext#
 #set.seed(1); qlnorm(0, 10, 10, lower.tail=FALSE, log.p=FALSE)
 [1] Inf
 
-##com.oracle.truffle.r.test.library.stats.TestStatFunctions.testFunctions32#Output.IgnoreWhitespace#
+##com.oracle.truffle.r.test.library.stats.TestStatFunctions.testFunctions32#Output.MayIgnoreWarningContext#
 #set.seed(1); qlnorm(0, 10, 10, lower.tail=FALSE, log.p=TRUE)
 [1] 0
 
-##com.oracle.truffle.r.test.library.stats.TestStatFunctions.testFunctions32#Output.IgnoreWhitespace#
+##com.oracle.truffle.r.test.library.stats.TestStatFunctions.testFunctions32#Output.MayIgnoreWarningContext#
 #set.seed(1); qlnorm(0, 10, 10, lower.tail=TRUE, log.p=FALSE)
 [1] 0
 
-##com.oracle.truffle.r.test.library.stats.TestStatFunctions.testFunctions32#Output.IgnoreWhitespace#
+##com.oracle.truffle.r.test.library.stats.TestStatFunctions.testFunctions32#Output.MayIgnoreWarningContext#
 #set.seed(1); qlnorm(0, 10, 10, lower.tail=TRUE, log.p=TRUE)
 [1] Inf
 
-##com.oracle.truffle.r.test.library.stats.TestStatFunctions.testFunctions32#Output.IgnoreWhitespace#
+##com.oracle.truffle.r.test.library.stats.TestStatFunctions.testFunctions32#Output.MayIgnoreWarningContext#
 #set.seed(1); qlnorm(0, c(0.0653, 0.000123, 32e-80, 8833, 79e70, 0, -1), rep(c(0.0653, 0.000123, 32e-80, 8833, 79e70), 7), lower.tail=FALSE, log.p=FALSE)
  [1] Inf Inf Inf Inf Inf Inf Inf Inf Inf Inf Inf Inf Inf Inf Inf Inf Inf Inf Inf
 [20] Inf Inf Inf Inf Inf Inf Inf Inf Inf Inf Inf Inf Inf Inf Inf Inf
 
-##com.oracle.truffle.r.test.library.stats.TestStatFunctions.testFunctions32#Output.IgnoreWhitespace#
+##com.oracle.truffle.r.test.library.stats.TestStatFunctions.testFunctions32#Output.MayIgnoreWarningContext#
 #set.seed(1); qlnorm(0, c(0.0653, 0.000123, 32e-80, 8833, 79e70, 0, -1), rep(c(0.0653, 0.000123, 32e-80, 8833, 79e70), 7), lower.tail=FALSE, log.p=TRUE)
  [1] 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
 
-##com.oracle.truffle.r.test.library.stats.TestStatFunctions.testFunctions32#Output.IgnoreWhitespace#
+##com.oracle.truffle.r.test.library.stats.TestStatFunctions.testFunctions32#Output.MayIgnoreWarningContext#
 #set.seed(1); qlnorm(0, c(0.0653, 0.000123, 32e-80, 8833, 79e70, 0, -1), rep(c(0.0653, 0.000123, 32e-80, 8833, 79e70), 7), lower.tail=TRUE, log.p=FALSE)
  [1] 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
 
-##com.oracle.truffle.r.test.library.stats.TestStatFunctions.testFunctions32#Output.IgnoreWhitespace#
+##com.oracle.truffle.r.test.library.stats.TestStatFunctions.testFunctions32#Output.MayIgnoreWarningContext#
 #set.seed(1); qlnorm(0, c(0.0653, 0.000123, 32e-80, 8833, 79e70, 0, -1), rep(c(0.0653, 0.000123, 32e-80, 8833, 79e70), 7), lower.tail=TRUE, log.p=TRUE)
  [1] Inf Inf Inf Inf Inf Inf Inf Inf Inf Inf Inf Inf Inf Inf Inf Inf Inf Inf Inf
 [20] Inf Inf Inf Inf Inf Inf Inf Inf Inf Inf Inf Inf Inf Inf Inf Inf
 
-##com.oracle.truffle.r.test.library.stats.TestStatFunctions.testFunctions32#Output.IgnoreWhitespace#
+##com.oracle.truffle.r.test.library.stats.TestStatFunctions.testFunctions32#Output.MayIgnoreWarningContext#
 #set.seed(1); qlnorm(c(-1, 0, 0.2, 2), c(-1, 0, 0.1, 0.9, 3), rep(c(-1, 0, 1, 0.1, -0.1, 0.0001), 20), lower.tail=FALSE, log.p=FALSE)
   [1]        NaN        Inf  2.5641351        NaN        NaN        Inf
   [7]        NaN        NaN        NaN        Inf        NaN        NaN
@@ -115854,7 +120211,7 @@ Warning message:
 In qlnorm(c(-1, 0, 0.2, 2), c(-1, 0, 0.1, 0.9, 3), rep(c(-1, 0,  :
   NaNs produced
 
-##com.oracle.truffle.r.test.library.stats.TestStatFunctions.testFunctions32#Output.IgnoreWhitespace#
+##com.oracle.truffle.r.test.library.stats.TestStatFunctions.testFunctions32#Output.MayIgnoreWarningContext#
 #set.seed(1); qlnorm(c(-1, 0, 0.2, 2), c(-1, 0, 0.1, 0.9, 3), rep(c(-1, 0, 1, 0.1, -0.1, 0.0001), 20), lower.tail=FALSE, log.p=TRUE)
   [1]        NaN  0.0000000        NaN        NaN        NaN  0.0000000
   [7]        NaN        NaN  3.4468989  0.0000000        NaN        NaN
@@ -115880,7 +120237,7 @@ Warning message:
 In qlnorm(c(-1, 0, 0.2, 2), c(-1, 0, 0.1, 0.9, 3), rep(c(-1, 0,  :
   NaNs produced
 
-##com.oracle.truffle.r.test.library.stats.TestStatFunctions.testFunctions32#Output.IgnoreWhitespace#
+##com.oracle.truffle.r.test.library.stats.TestStatFunctions.testFunctions32#Output.MayIgnoreWarningContext#
 #set.seed(1); qlnorm(c(-1, 0, 0.2, 2), c(-1, 0, 0.1, 0.9, 3), rep(c(-1, 0, 1, 0.1, -0.1, 0.0001), 20), lower.tail=TRUE, log.p=FALSE)
   [1]       NaN 0.0000000 0.4763410       NaN       NaN 0.0000000       NaN
   [8]       NaN       NaN 0.0000000       NaN       NaN       NaN 0.0000000
@@ -115904,7 +120261,7 @@ Warning message:
 In qlnorm(c(-1, 0, 0.2, 2), c(-1, 0, 0.1, 0.9, 3), rep(c(-1, 0,  :
   NaNs produced
 
-##com.oracle.truffle.r.test.library.stats.TestStatFunctions.testFunctions32#Output.IgnoreWhitespace#
+##com.oracle.truffle.r.test.library.stats.TestStatFunctions.testFunctions32#Output.MayIgnoreWarningContext#
 #set.seed(1); qlnorm(c(-1, 0, 0.2, 2), c(-1, 0, 0.1, 0.9, 3), rep(c(-1, 0, 1, 0.1, -0.1, 0.0001), 20), lower.tail=TRUE, log.p=TRUE)
   [1]        NaN        Inf        NaN        NaN        NaN        Inf
   [7]        NaN        NaN  1.7550986        Inf        NaN        NaN
@@ -115930,20 +120287,20 @@ Warning message:
 In qlnorm(c(-1, 0, 0.2, 2), c(-1, 0, 0.1, 0.9, 3), rep(c(-1, 0,  :
   NaNs produced
 
-##com.oracle.truffle.r.test.library.stats.TestStatFunctions.testFunctions32#Output.IgnoreWarningContext#
+##com.oracle.truffle.r.test.library.stats.TestStatFunctions.testFunctions32#Output.MayIgnoreWarningContext#
 #set.seed(1); qlnorm(c(NA, 0, NaN, 1/0, -1/0), rep(c(1, 0, 0.1), 5), rep(c(1, 0, 0.1), 5))
  [1]  NA   0 NaN NaN NaN  NA   0 NaN NaN NaN  NA   0 NaN NaN NaN
 Warning message:
 In qlnorm(c(NA, 0, NaN, 1/0, -1/0), rep(c(1, 0, 0.1), 5), rep(c(1,  :
   NaNs produced
 
-##com.oracle.truffle.r.test.library.stats.TestStatFunctions.testFunctions32#Output.IgnoreWarningContext#
+##com.oracle.truffle.r.test.library.stats.TestStatFunctions.testFunctions32#Output.MayIgnoreWarningContext#
 #set.seed(1); qlnorm(rep(c(1, 0, 0.1), 5), c(NA, 0, NaN, 1/0, -1/0), rep(c(1, 0, 0.1), 5))
  [1]        NA 0.0000000       NaN       Inf 0.0000000        NA       Inf
  [8]       NaN       Inf       Inf        NA 0.8797169       NaN 0.0000000
 [15] 0.0000000
 
-##com.oracle.truffle.r.test.library.stats.TestStatFunctions.testFunctions32#Output.IgnoreWhitespace#
+##com.oracle.truffle.r.test.library.stats.TestStatFunctions.testFunctions32#Output.MayIgnoreWarningContext#
 #set.seed(1); qlnorm(rep(c(1, 0, 0.1), 5), rep(c(1, 0, 0.1), 5), c(NA, 0, NaN, 1/0, -1/0))
  [1]       NA 0.000000      NaN      Inf 0.000000       NA      Inf      NaN
  [9] 0.000000      Inf       NA 1.105171      NaN 0.000000      NaN
@@ -115951,6 +120308,166 @@ Warning message:
 In qlnorm(rep(c(1, 0, 0.1), 5), rep(c(1, 0, 0.1), 5), c(NA, 0, NaN,  :
   NaNs produced
 
+##com.oracle.truffle.r.test.library.stats.TestStatFunctions.testFunctions32#Output.MayIgnoreWarningContext#
+#set.seed(1); qlogis(0, 10, 10, lower.tail=FALSE, log.p=FALSE)
+[1] Inf
+
+##com.oracle.truffle.r.test.library.stats.TestStatFunctions.testFunctions32#Output.MayIgnoreWarningContext#
+#set.seed(1); qlogis(0, 10, 10, lower.tail=FALSE, log.p=TRUE)
+[1] -Inf
+
+##com.oracle.truffle.r.test.library.stats.TestStatFunctions.testFunctions32#Output.MayIgnoreWarningContext#
+#set.seed(1); qlogis(0, 10, 10, lower.tail=TRUE, log.p=FALSE)
+[1] -Inf
+
+##com.oracle.truffle.r.test.library.stats.TestStatFunctions.testFunctions32#Output.MayIgnoreWarningContext#
+#set.seed(1); qlogis(0, 10, 10, lower.tail=TRUE, log.p=TRUE)
+[1] Inf
+
+##com.oracle.truffle.r.test.library.stats.TestStatFunctions.testFunctions32#Output.MayIgnoreWarningContext#
+#set.seed(1); qlogis(0, c(0.0653, 0.000123, 32e-80, 8833, 79e70, 0, -1), rep(c(0.0653, 0.000123, 32e-80, 8833, 79e70), 7), lower.tail=FALSE, log.p=FALSE)
+ [1] Inf Inf Inf Inf Inf Inf Inf Inf Inf Inf Inf Inf Inf Inf Inf Inf Inf Inf Inf
+[20] Inf Inf Inf Inf Inf Inf Inf Inf Inf Inf Inf Inf Inf Inf Inf Inf
+
+##com.oracle.truffle.r.test.library.stats.TestStatFunctions.testFunctions32#Output.MayIgnoreWarningContext#
+#set.seed(1); qlogis(0, c(0.0653, 0.000123, 32e-80, 8833, 79e70, 0, -1), rep(c(0.0653, 0.000123, 32e-80, 8833, 79e70), 7), lower.tail=FALSE, log.p=TRUE)
+ [1] -Inf -Inf -Inf -Inf -Inf -Inf -Inf -Inf -Inf -Inf -Inf -Inf -Inf -Inf -Inf
+[16] -Inf -Inf -Inf -Inf -Inf -Inf -Inf -Inf -Inf -Inf -Inf -Inf -Inf -Inf -Inf
+[31] -Inf -Inf -Inf -Inf -Inf
+
+##com.oracle.truffle.r.test.library.stats.TestStatFunctions.testFunctions32#Output.MayIgnoreWarningContext#
+#set.seed(1); qlogis(0, c(0.0653, 0.000123, 32e-80, 8833, 79e70, 0, -1), rep(c(0.0653, 0.000123, 32e-80, 8833, 79e70), 7), lower.tail=TRUE, log.p=FALSE)
+ [1] -Inf -Inf -Inf -Inf -Inf -Inf -Inf -Inf -Inf -Inf -Inf -Inf -Inf -Inf -Inf
+[16] -Inf -Inf -Inf -Inf -Inf -Inf -Inf -Inf -Inf -Inf -Inf -Inf -Inf -Inf -Inf
+[31] -Inf -Inf -Inf -Inf -Inf
+
+##com.oracle.truffle.r.test.library.stats.TestStatFunctions.testFunctions32#Output.MayIgnoreWarningContext#
+#set.seed(1); qlogis(0, c(0.0653, 0.000123, 32e-80, 8833, 79e70, 0, -1), rep(c(0.0653, 0.000123, 32e-80, 8833, 79e70), 7), lower.tail=TRUE, log.p=TRUE)
+ [1] Inf Inf Inf Inf Inf Inf Inf Inf Inf Inf Inf Inf Inf Inf Inf Inf Inf Inf Inf
+[20] Inf Inf Inf Inf Inf Inf Inf Inf Inf Inf Inf Inf Inf Inf Inf Inf
+
+##com.oracle.truffle.r.test.library.stats.TestStatFunctions.testFunctions32#Output.MayIgnoreWarningContext#
+#set.seed(1); qlogis(c(-1, 0, 0.2, 2), c(-1, 0, 0.1, 0.9, 3), rep(c(-1, 0, 1, 0.1, -0.1, 0.0001), 20), lower.tail=FALSE, log.p=FALSE)
+  [1]       NaN       Inf 1.4862944       NaN       NaN       Inf       NaN
+  [8]       NaN       NaN       Inf       NaN       NaN       NaN       Inf
+ [15] 4.3862944       NaN       NaN       Inf       NaN       NaN       NaN
+ [22]       Inf       NaN       NaN       NaN       Inf 1.3862944       NaN
+ [29]       NaN       Inf       NaN       NaN       NaN       Inf       NaN
+ [36]       NaN       NaN       Inf 2.2862944       NaN       NaN       Inf
+ [43]       NaN       NaN       NaN       Inf       NaN       NaN       NaN
+ [50]       Inf 0.3862944       NaN       NaN       Inf       NaN       NaN
+ [57]       NaN       Inf       NaN       NaN       NaN       Inf 1.4862944
+ [64]       NaN       NaN       Inf       NaN       NaN       NaN       Inf
+ [71]       NaN       NaN       NaN       Inf 4.3862944       NaN       NaN
+ [78]       Inf       NaN       NaN       NaN       Inf       NaN       NaN
+ [85]       NaN       Inf 1.3862944       NaN       NaN       Inf       NaN
+ [92]       NaN       NaN       Inf       NaN       NaN       NaN       Inf
+ [99] 2.2862944       NaN       NaN       Inf       NaN       NaN       NaN
+[106]       Inf       NaN       NaN       NaN       Inf 0.3862944       NaN
+[113]       NaN       Inf       NaN       NaN       NaN       Inf       NaN
+[120]       NaN
+Warning message:
+In qlogis(c(-1, 0, 0.2, 2), c(-1, 0, 0.1, 0.9, 3), rep(c(-1, 0,  :
+  NaNs produced
+
+##com.oracle.truffle.r.test.library.stats.TestStatFunctions.testFunctions32#Output.MayIgnoreWarningContext#
+#set.seed(1); qlogis(c(-1, 0, 0.2, 2), c(-1, 0, 0.1, 0.9, 3), rep(c(-1, 0, 1, 0.1, -0.1, 0.0001), 20), lower.tail=FALSE, log.p=TRUE)
+  [1]        NaN       -Inf        NaN        NaN        NaN       -Inf
+  [7]        NaN        NaN  1.4413249       -Inf        NaN        NaN
+ [13]        NaN       -Inf        NaN        NaN        NaN       -Inf
+ [19]        NaN        NaN -0.4586751       -Inf        NaN        NaN
+ [25]        NaN       -Inf        NaN        NaN        NaN       -Inf
+ [31]        NaN        NaN  0.6413249       -Inf        NaN        NaN
+ [37]        NaN       -Inf        NaN        NaN        NaN       -Inf
+ [43]        NaN        NaN  3.5413249       -Inf        NaN        NaN
+ [49]        NaN       -Inf        NaN        NaN        NaN       -Inf
+ [55]        NaN        NaN  0.5413249       -Inf        NaN        NaN
+ [61]        NaN       -Inf        NaN        NaN        NaN       -Inf
+ [67]        NaN        NaN  1.4413249       -Inf        NaN        NaN
+ [73]        NaN       -Inf        NaN        NaN        NaN       -Inf
+ [79]        NaN        NaN -0.4586751       -Inf        NaN        NaN
+ [85]        NaN       -Inf        NaN        NaN        NaN       -Inf
+ [91]        NaN        NaN  0.6413249       -Inf        NaN        NaN
+ [97]        NaN       -Inf        NaN        NaN        NaN       -Inf
+[103]        NaN        NaN  3.5413249       -Inf        NaN        NaN
+[109]        NaN       -Inf        NaN        NaN        NaN       -Inf
+[115]        NaN        NaN  0.5413249       -Inf        NaN        NaN
+Warning message:
+In qlogis(c(-1, 0, 0.2, 2), c(-1, 0, 0.1, 0.9, 3), rep(c(-1, 0,  :
+  NaNs produced
+
+##com.oracle.truffle.r.test.library.stats.TestStatFunctions.testFunctions32#Output.MayIgnoreWarningContext#
+#set.seed(1); qlogis(c(-1, 0, 0.2, 2), c(-1, 0, 0.1, 0.9, 3), rep(c(-1, 0, 1, 0.1, -0.1, 0.0001), 20), lower.tail=TRUE, log.p=FALSE)
+  [1]        NaN       -Inf -1.2862944        NaN        NaN       -Inf
+  [7]        NaN        NaN        NaN       -Inf        NaN        NaN
+ [13]        NaN       -Inf  1.6137056        NaN        NaN       -Inf
+ [19]        NaN        NaN        NaN       -Inf        NaN        NaN
+ [25]        NaN       -Inf -1.3862944        NaN        NaN       -Inf
+ [31]        NaN        NaN        NaN       -Inf        NaN        NaN
+ [37]        NaN       -Inf -0.4862944        NaN        NaN       -Inf
+ [43]        NaN        NaN        NaN       -Inf        NaN        NaN
+ [49]        NaN       -Inf -2.3862944        NaN        NaN       -Inf
+ [55]        NaN        NaN        NaN       -Inf        NaN        NaN
+ [61]        NaN       -Inf -1.2862944        NaN        NaN       -Inf
+ [67]        NaN        NaN        NaN       -Inf        NaN        NaN
+ [73]        NaN       -Inf  1.6137056        NaN        NaN       -Inf
+ [79]        NaN        NaN        NaN       -Inf        NaN        NaN
+ [85]        NaN       -Inf -1.3862944        NaN        NaN       -Inf
+ [91]        NaN        NaN        NaN       -Inf        NaN        NaN
+ [97]        NaN       -Inf -0.4862944        NaN        NaN       -Inf
+[103]        NaN        NaN        NaN       -Inf        NaN        NaN
+[109]        NaN       -Inf -2.3862944        NaN        NaN       -Inf
+[115]        NaN        NaN        NaN       -Inf        NaN        NaN
+Warning message:
+In qlogis(c(-1, 0, 0.2, 2), c(-1, 0, 0.1, 0.9, 3), rep(c(-1, 0,  :
+  NaNs produced
+
+##com.oracle.truffle.r.test.library.stats.TestStatFunctions.testFunctions32#Output.MayIgnoreWarningContext#
+#set.seed(1); qlogis(c(-1, 0, 0.2, 2), c(-1, 0, 0.1, 0.9, 3), rep(c(-1, 0, 1, 0.1, -0.1, 0.0001), 20), lower.tail=TRUE, log.p=TRUE)
+  [1]        NaN        Inf        NaN        NaN        NaN        Inf
+  [7]        NaN        NaN  0.3586751        Inf        NaN        NaN
+ [13]        NaN        Inf        NaN        NaN        NaN        Inf
+ [19]        NaN        NaN -1.5413249        Inf        NaN        NaN
+ [25]        NaN        Inf        NaN        NaN        NaN        Inf
+ [31]        NaN        NaN -0.4413249        Inf        NaN        NaN
+ [37]        NaN        Inf        NaN        NaN        NaN        Inf
+ [43]        NaN        NaN  2.4586751        Inf        NaN        NaN
+ [49]        NaN        Inf        NaN        NaN        NaN        Inf
+ [55]        NaN        NaN -0.5413249        Inf        NaN        NaN
+ [61]        NaN        Inf        NaN        NaN        NaN        Inf
+ [67]        NaN        NaN  0.3586751        Inf        NaN        NaN
+ [73]        NaN        Inf        NaN        NaN        NaN        Inf
+ [79]        NaN        NaN -1.5413249        Inf        NaN        NaN
+ [85]        NaN        Inf        NaN        NaN        NaN        Inf
+ [91]        NaN        NaN -0.4413249        Inf        NaN        NaN
+ [97]        NaN        Inf        NaN        NaN        NaN        Inf
+[103]        NaN        NaN  2.4586751        Inf        NaN        NaN
+[109]        NaN        Inf        NaN        NaN        NaN        Inf
+[115]        NaN        NaN -0.5413249        Inf        NaN        NaN
+Warning message:
+In qlogis(c(-1, 0, 0.2, 2), c(-1, 0, 0.1, 0.9, 3), rep(c(-1, 0,  :
+  NaNs produced
+
+##com.oracle.truffle.r.test.library.stats.TestStatFunctions.testFunctions32#Output.MayIgnoreWarningContext#
+#set.seed(1); qlogis(c(NA, 0, NaN, 1/0, -1/0), rep(c(1, 0, 0.1), 5), rep(c(1, 0, 0.1), 5))
+ [1]   NA -Inf  NaN  NaN  NaN   NA -Inf  NaN  NaN  NaN   NA -Inf  NaN  NaN  NaN
+Warning message:
+In qlogis(c(NA, 0, NaN, 1/0, -1/0), rep(c(1, 0, 0.1), 5), rep(c(1,  :
+  NaNs produced
+
+##com.oracle.truffle.r.test.library.stats.TestStatFunctions.testFunctions32#Output.MayIgnoreWarningContext#
+#set.seed(1); qlogis(rep(c(1, 0, 0.1), 5), c(NA, 0, NaN, 1/0, -1/0), rep(c(1, 0, 0.1), 5))
+ [1]         NA       -Inf        NaN        Inf       -Inf         NA
+ [7]        Inf        NaN        Inf        Inf         NA -0.2197225
+[13]        NaN       -Inf       -Inf
+
+##com.oracle.truffle.r.test.library.stats.TestStatFunctions.testFunctions32#Output.MayIgnoreWarningContext#
+#set.seed(1); qlogis(rep(c(1, 0, 0.1), 5), rep(c(1, 0, 0.1), 5), c(NA, 0, NaN, 1/0, -1/0))
+ [1]   NA -Inf  NaN  Inf -Inf   NA  Inf  NaN -Inf  Inf   NA  0.1  NaN -Inf  NaN
+Warning message:
+In qlogis(rep(c(1, 0, 0.1), 5), rep(c(1, 0, 0.1), 5), c(NA, 0, NaN,  :
+  NaNs produced
+
 ##com.oracle.truffle.r.test.library.stats.TestStats.testCor#
 #{ as.integer(cor(c(1,2,3),c(1,2,5))*10000000) }
 [1] 9607689
@@ -117333,6 +121850,10 @@ NULL
 #{ library("testrffi", lib.loc = "tmptest/com.oracle.truffle.r.test.rpackages"); x <- rffi.addDouble(2, 3); detach("package:testrffi", unload=T); x }
 [1] 5
 
+##com.oracle.truffle.r.test.rffi.TestRFFIPackage.testRFFI20#
+#{ library("testrffi", lib.loc = "tmptest/com.oracle.truffle.r.test.rpackages"); x <- "12345"; x <- rffi.char_length(x); detach("package:testrffi", unload=T); x }
+[1] 5
+
 ##com.oracle.truffle.r.test.rffi.TestRFFIPackage.testRFFI3#
 #{ library("testrffi", lib.loc = "tmptest/com.oracle.truffle.r.test.rpackages"); x <- rffi.populateIntVector(5); detach("package:testrffi", unload=T); x }
 [1] 0 1 2 3 4
diff --git a/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/TestBase.java b/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/TestBase.java
index f656624b7f3cf7bf6b8c14429c58b02229d9dd74..173cc5b2b3ddf1a23bf6aabb63ebdbaf60f3b7a0 100644
--- a/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/TestBase.java
+++ b/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/TestBase.java
@@ -22,6 +22,8 @@ import java.nio.file.Paths;
 import java.nio.file.SimpleFileVisitor;
 import java.nio.file.attribute.BasicFileAttributes;
 import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.EnumSet;
 import java.util.HashMap;
 import java.util.Map.Entry;
 import java.util.SortedMap;
@@ -63,14 +65,17 @@ public class TestBase {
 
     public static final boolean ProcessFailedTests = Boolean.getBoolean("ProcessFailedTests");
 
+    /**
+     * See {@link com.oracle.truffle.r.test.builtins.TestTestBase} for examples.
+     */
     public enum Output implements TestTrait {
         IgnoreErrorContext, // the error context is ignored (e.g., "a+b" vs. "a + b")
         IgnoreErrorMessage, // the actual error message is ignored
         IgnoreWarningContext, // the warning context is ignored
-        MayIgnoreErrorContext,
+        MayIgnoreErrorContext, // like IgnoreErrorContext, but no warning if the messages match
         MayIgnoreWarningContext,
         ContainsReferences, // replaces references in form of 0xbcdef1 for numbers
-        IgnoreWhitespace;
+        IgnoreWhitespace; // removes all whitespace from the whole output
 
         @Override
         public String getName() {
@@ -572,37 +577,51 @@ public class TestBase {
         }
     }
 
-    private void evalAndCompare(String[] inputs, TestTrait... traits) {
-        WhiteList[] whiteLists = TestTrait.collect(traits, WhiteList.class);
-
-        boolean ignored = TestTrait.contains(traits, Ignored.class) ^ (ProcessFailedTests && !(TestTrait.contains(traits, Ignored.Unstable) || TestTrait.contains(traits, Ignored.SideEffects)));
+    /**
+     * Wraps the traits, there are some meta-traits like {@link #isIgnored}, other traits can be
+     * accessed through the corresponding enum-set.
+     */
+    private static class TestTraitsSet {
+        EnumSet<Ignored> ignored = EnumSet.noneOf(Ignored.class);
+        EnumSet<Output> output = EnumSet.noneOf(Output.class);
+        EnumSet<Context> context = EnumSet.noneOf(Context.class);
+        boolean isIgnored;
+        boolean containsError;
+
+        TestTraitsSet(TestTrait[] traits) {
+            ignored.addAll(Arrays.asList(TestTrait.collect(traits, Ignored.class)));
+            output.addAll(Arrays.asList(TestTrait.collect(traits, Output.class)));
+            context.addAll(Arrays.asList(TestTrait.collect(traits, Context.class)));
+            containsError = (!FULL_COMPARE_ERRORS && (output.contains(Output.IgnoreErrorContext) || output.contains(Output.IgnoreErrorMessage)));
+            isIgnored = ignored.size() > 0 ^ (ProcessFailedTests && !(ignored.contains(Ignored.Unstable) || ignored.contains(Ignored.SideEffects)));
+            assert !output.contains(Output.IgnoreWhitespace) || output.size() == 1 : "IgnoreWhitespace trait does not work with any other Output trait";
 
-        boolean containsWarning = TestTrait.contains(traits, Output.IgnoreWarningContext);
-        boolean containsError = (!FULL_COMPARE_ERRORS && (TestTrait.contains(traits, Output.IgnoreErrorContext) || TestTrait.contains(traits, Output.IgnoreErrorMessage)));
-        boolean mayContainWarning = TestTrait.contains(traits, Output.MayIgnoreWarningContext);
-        boolean mayContainError = TestTrait.contains(traits, Output.MayIgnoreErrorContext);
-        boolean ambiguousError = TestTrait.contains(traits, Output.IgnoreErrorMessage);
-        boolean ignoreWhitespace = TestTrait.contains(traits, Output.IgnoreWhitespace);
-        boolean containsReferences = TestTrait.contains(traits, Output.ContainsReferences);
-        boolean nonSharedContext = TestTrait.contains(traits, Context.NonShared);
-        boolean longTimeout = TestTrait.contains(traits, Context.LongTimeout);
+        }
 
-        ContextInfo contextInfo = nonSharedContext ? fastROutputManager.fastRSession.createContextInfo(ContextKind.SHARE_NOTHING) : null;
+        String preprocessOutput(String out) {
+            if (output.contains(Output.IgnoreWhitespace)) {
+                return out.replaceAll("\\s+", "");
+            }
+            if (output.contains(Output.ContainsReferences)) {
+                return convertReferencesInOutput(out);
+            }
+            return out;
+        }
+    }
 
+    private void evalAndCompare(String[] inputs, TestTrait... traitsList) {
+        WhiteList[] whiteLists = TestTrait.collect(traitsList, WhiteList.class);
+        TestTraitsSet traits = new TestTraitsSet(traitsList);
+        ContextInfo contextInfo = traits.context.contains(Context.NonShared) ? fastROutputManager.fastRSession.createContextInfo(ContextKind.SHARE_NOTHING) : null;
         int index = 1;
         boolean allOk = true;
         for (String input : inputs) {
-            String expected = expectedEval(input, traits);
-            if (ignored || generatingExpected()) {
+            String expected = expectedEval(input, traitsList);
+            if (traits.isIgnored || generatingExpected()) {
                 ignoredInputCount++;
             } else {
-                String result = fastREval(input, contextInfo, longTimeout);
-                if (ignoreWhitespace) {
-                    expected = expected.replaceAll("\\s+", "");
-                    result = result.replaceAll("\\s+", "");
-                }
-
-                CheckResult checkResult = checkResult(whiteLists, input, expected, result, containsWarning, mayContainWarning, containsError, mayContainError, ambiguousError, containsReferences);
+                String result = fastREval(input, contextInfo, traits.context.contains(Context.LongTimeout));
+                CheckResult checkResult = checkResult(whiteLists, input, traits.preprocessOutput(expected), traits.preprocessOutput(result), traits);
 
                 result = checkResult.result;
                 expected = checkResult.expected;
@@ -638,7 +657,7 @@ public class TestBase {
             }
             index++;
         }
-        if (ignored) {
+        if (traits.isIgnored) {
             ignoredTestCount++;
         } else if (allOk) {
             successfulTestCount++;
@@ -660,25 +679,20 @@ public class TestBase {
         }
     }
 
-    private CheckResult checkResult(WhiteList[] whiteLists, String input, String originalExpected, String originalResult, boolean containsWarning, boolean mayContainWarning, boolean containsError,
-                    boolean mayContainError, boolean ambiguousError, boolean convertReferences) {
+    private CheckResult checkResult(WhiteList[] whiteLists, String input, String originalExpected, String originalResult, TestTraitsSet traits) {
         boolean ok;
         String result = originalResult;
         String expected = originalExpected;
-        if (convertReferences) {
-            result = convertReferencesInOutput(result);
-            expected = convertReferencesInOutput(expected);
-        }
-        if (expected.equals(result) || searchWhiteLists(whiteLists, input, expected, result, containsWarning, mayContainWarning, containsError, mayContainError, ambiguousError, convertReferences)) {
+        if (expected.equals(result) || searchWhiteLists(whiteLists, input, expected, result, traits)) {
             ok = true;
-            if (containsError && !ambiguousError) {
+            if (traits.containsError && !traits.output.contains(Output.IgnoreErrorMessage)) {
                 System.out.println("unexpected correct error message: " + getTestContext());
             }
-            if (containsWarning) {
+            if (traits.output.contains(Output.IgnoreWarningContext)) {
                 System.out.println("unexpected correct warning message: " + getTestContext());
             }
         } else {
-            if (containsWarning || (mayContainWarning && expected.contains(WARNING))) {
+            if (traits.output.contains(Output.IgnoreWarningContext) || (traits.output.contains(Output.MayIgnoreWarningContext) && expected.contains(WARNING))) {
                 String resultWarning = getWarningMessage(result);
                 String expectedWarning = getWarningMessage(expected);
                 ok = resultWarning.equals(expectedWarning);
@@ -688,8 +702,8 @@ public class TestBase {
                 ok = true;
             }
             if (ok) {
-                if (containsError || (mayContainError && expected.startsWith(ERROR))) {
-                    ok = result.startsWith(ERROR) && (ambiguousError || checkMessageStripped(expected, result) || checkMessageVectorInIndex(expected, result));
+                if (traits.containsError || (traits.output.contains(Output.MayIgnoreErrorContext) && expected.startsWith(ERROR))) {
+                    ok = result.startsWith(ERROR) && (traits.output.contains(Output.IgnoreErrorMessage) || checkMessageStripped(expected, result) || checkMessageVectorInIndex(expected, result));
                 } else {
                     ok = expected.equals(result);
                 }
@@ -714,8 +728,7 @@ public class TestBase {
         return result;
     }
 
-    private boolean searchWhiteLists(WhiteList[] whiteLists, String input, String expected, String result, boolean containsWarning, boolean mayContainWarning, boolean containsError,
-                    boolean mayContainError, boolean ambiguousError, boolean convertReferences) {
+    private boolean searchWhiteLists(WhiteList[] whiteLists, String input, String expected, String result, TestTraitsSet testTraits) {
         if (whiteLists == null) {
             return false;
         }
@@ -723,13 +736,13 @@ public class TestBase {
             WhiteList.Results wlr = list.get(input);
             if (wlr != null) {
                 // Sanity check that "expected" matches the entry in the WhiteList
-                CheckResult checkedResult = checkResult(null, input, wlr.expected, expected, containsWarning, mayContainWarning, containsError, mayContainError, ambiguousError, convertReferences);
+                CheckResult checkedResult = checkResult(null, input, wlr.expected, expected, testTraits);
                 if (!checkedResult.ok) {
                     System.out.println("expected output does not match: " + wlr.expected + " vs. " + expected);
                     return false;
                 }
                 // Substitute the FastR output and try to match that
-                CheckResult fastRResult = checkResult(null, input, wlr.fastR, result, containsWarning, mayContainWarning, containsError, mayContainError, ambiguousError, convertReferences);
+                CheckResult fastRResult = checkResult(null, input, wlr.fastR, result, testTraits);
                 if (fastRResult.ok) {
                     list.markUsed(input);
                     return true;
@@ -745,7 +758,7 @@ public class TestBase {
     private static final Pattern warningPattern4 = Pattern.compile("^(?<pre>.*)Warning messages:\n1:(?<msg0>.*)\n2:(?<msg1>.*)$", Pattern.DOTALL);
     private static final Pattern warningPattern5 = Pattern.compile("^(?<pre>.*)Warning message:(?<msg0>.*)$", Pattern.DOTALL);
 
-    private static final Pattern warningMessagePattern = Pattern.compile("^\n? ? ?(?:In .* :[ \n])?(?<m>[^\n]*)\n?$", Pattern.DOTALL);
+    private static final Pattern warningMessagePattern = Pattern.compile("^\n? ? ?(?:In .* :[ \n])?[ \n]*(?<m>[^\n]*)\n?$", Pattern.DOTALL);
 
     private static final Pattern[] warningPatterns = new Pattern[]{warningPattern1, warningPattern2, warningPattern3, warningPattern4, warningPattern5};
 
diff --git a/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/builtins/TestBuiltin_array.java b/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/builtins/TestBuiltin_array.java
index f3d72b9a76b32238317d54dcd86a78a788e09ede..c59d7c4c04748914777a44ed2f9dac95b652b373 100644
--- a/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/builtins/TestBuiltin_array.java
+++ b/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/builtins/TestBuiltin_array.java
@@ -70,8 +70,7 @@ public class TestBuiltin_array extends TestBase {
 
     @Test
     public void testarray11() {
-        assertEval(Ignored.Unknown,
-                        "argv <- list(list(NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL), 8L, list(c('1', '2', '3', '4', '5', '6', '7', '8'))); .Internal(array(argv[[1]], argv[[2]], argv[[3]]))");
+        assertEval("argv <- list(list(NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL), 8L, list(c('1', '2', '3', '4', '5', '6', '7', '8'))); .Internal(array(argv[[1]], argv[[2]], argv[[3]]))");
     }
 
     @Test
diff --git a/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/builtins/TestBuiltin_attrassign.java b/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/builtins/TestBuiltin_attrassign.java
index b8b553bad99c00077d46ab1bd2902978b4fab2f2..ab83f538b284c7c7cf469045ea726e1c386b427e 100644
--- a/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/builtins/TestBuiltin_attrassign.java
+++ b/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/builtins/TestBuiltin_attrassign.java
@@ -98,6 +98,12 @@ public class TestBuiltin_attrassign extends TestBase {
         assertEval("argv <- list(structure(c(0, -187, -34, 0, 165, 0, -95, 121, 107, 0, 41, 0, 0, 93, 0), .Dim = c(5L, 3L)), 'dimnames', value = NULL);`attr<-`(argv[[1]],argv[[2]],argv[[3]]);");
     }
 
+    @Test
+    public void testRefCount() {
+        assertEval("x <- c(1,2); attr(x, \"foo\") <- c(\"a\",\"b\"); y <- x; attr(x,\"foo\")[[1]] <- \"c\"; y");
+        assertEval("x <- c(1,2,3); y <- 42; attr(y, 'at') <- x; x[[1]] <- 2; attr(y, 'at')");
+    }
+
     @Test
     public void testArgsCasts() {
         assertEval(Output.IgnoreErrorContext, "x<-42; attr(x, NULL) <- NULL");
diff --git a/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/builtins/TestBuiltin_crc64.java b/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/builtins/TestBuiltin_crc64.java
new file mode 100644
index 0000000000000000000000000000000000000000..46a350685807ec058e04582969772e62009ac049
--- /dev/null
+++ b/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/builtins/TestBuiltin_crc64.java
@@ -0,0 +1,68 @@
+/*
+ * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package com.oracle.truffle.r.test.builtins;
+
+import org.junit.Test;
+
+import com.oracle.truffle.r.test.TestBase;
+
+// Checkstyle: stop line length check
+public class TestBuiltin_crc64 extends TestBase {
+
+    @Test
+    public void testCrc64() {
+
+        assertEval("crc64()");
+        assertEval("crc64('a')");
+        assertEval(".Internal(crc64())");
+        assertEval(".Internal(crc64('a'))");
+        assertEval(".Internal(crc64(paste(c(letters, LETTERS, 0:9), collapse=\"\")))");
+        assertEval(".Internal(crc64(c('a')))");
+
+        // Expression: .Internal(crc64('a', 'b'))
+        // Expected output: Error: 2 arguments passed to .Internal(crc64) which requires 1
+        // FastR output: Error in crc64("a", "b") : unused argument ('b')
+        // should be handled in .Internal-s impl ?
+        assertEval(Ignored.ImplementationError, ".Internal(crc64('a', 'b'))");
+
+        assertEval(".Internal(crc64(c(1, 2)))");
+
+        assertEval(".Internal(crc64(c('a', 'b')))");
+
+        assertEval(".Internal(crc64(NA))");
+        assertEval(".Internal(crc64(NULL))");
+        assertEval(".Internal(crc64(list(list())))");
+        assertEval(".Internal(crc64(list(NULL)))");
+        assertEval(".Internal(crc64(c(NULL)))");
+
+        assertEval(".Internal(crc64(integer(0)))");
+        assertEval(".Internal(crc64(double(0)))");
+
+        assertEval(".Internal(crc64(01))");
+
+        assertEval(".Internal(crc64(new.env()))");
+        assertEval(".Internal(crc64(environment))");
+        assertEval(".Internal(crc64(stdout()))");
+    }
+
+}
diff --git a/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/builtins/TestBuiltin_docall.java b/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/builtins/TestBuiltin_docall.java
index 7f13a13bc2f4c91616bbfce1fad3e28de2933bdd..73fbac9e68fd11f22099a70addf59940d87cd915 100644
--- a/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/builtins/TestBuiltin_docall.java
+++ b/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/builtins/TestBuiltin_docall.java
@@ -29,5 +29,7 @@ public class TestBuiltin_docall extends TestBase {
         assertEval("{ do.call(\"+\", list(quote(1), 2))}");
         assertEval("v1 <- as.numeric_version('3.0.0'); v2 <- as.numeric_version('3.1.0'); do.call('<', list(v1, v2))");
         assertEval("v1 <- as.numeric_version('3.0.0'); v2 <- as.numeric_version('3.1.0'); do.call('<', list(quote(v1), quote(v2)))");
+        assertEval(Output.IgnoreErrorContext, "typeof(do.call(function(x) x, list(as.symbol('foo'))))");
+        assertEval("typeof(do.call(function(x) x, list(as.symbol('foo')), quote=TRUE))");
     }
 }
diff --git a/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/builtins/TestBuiltin_identical.java b/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/builtins/TestBuiltin_identical.java
index d2fdc75685a637c5ee7d4bb80484fef5a580ecc2..83259357950962b4bcd8cebdc2140aa8955902e2 100644
--- a/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/builtins/TestBuiltin_identical.java
+++ b/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/builtins/TestBuiltin_identical.java
@@ -154,7 +154,7 @@ public class TestBuiltin_identical extends TestBase {
 
     @Test
     public void testidentical28() {
-        assertEval(Ignored.Unknown,
+        assertEval(Ignored.Unstable,
                         "argv <- list(structure(list(x = c(1, 1, 1, 1, 1, 1, 1, 1, 1, 1), y = c(1, 2, 3, 4, 5, 6, 7, 8, 9, 10), fac = structure(c(1L, 3L, 2L, 3L, 3L, 1L, 2L, 3L, 2L, 2L), .Label = c('A', 'B', 'C'), class = 'factor')), .Names = c('x', 'y', 'fac'), row.names = c(NA, -10L), class = 'data.frame'), structure(list(x = c(1, 1, 1, 1, 1, 1, 1, 1, 1, 1), y = c(1, 2, 3, 4, 5, 6, 7, 8, 9, 10), fac = structure(c(1L, 3L, 2L, 3L, 3L, 1L, 2L, 3L, 2L, 2L), .Label = c('A', 'B', 'C'), class = 'factor')), .Names = c('x', 'y', 'fac'), row.names = c(NA, 10L), class = 'data.frame'), TRUE, TRUE, TRUE, TRUE, FALSE); .Internal(identical(argv[[1]], argv[[2]], argv[[3]], argv[[4]], argv[[5]], argv[[6]], argv[[7]]))");
     }
 
diff --git a/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/builtins/TestBuiltin_list.java b/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/builtins/TestBuiltin_list.java
index 0317997c24916e2917819c231054d6cd5b44a61a..e612304d8f81c89851fe5e590a4f2646a6b5b891 100644
--- a/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/builtins/TestBuiltin_list.java
+++ b/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/builtins/TestBuiltin_list.java
@@ -347,6 +347,11 @@ public class TestBuiltin_list extends TestBase {
                         "argv <- list(ANY = structure(function (x, y = NULL) .Internal(crossprod(x, y)), target = structure('ANY', class = structure('signature', package = 'methods'), .Names = 'x', package = 'methods'), defined = structure('ANY', class = structure('signature', package = 'methods'), .Names = 'x', package = 'methods'), generic = structure('crossprod', package = 'base'), class = structure('derivedDefaultMethod', package = 'methods')));list(argv[[1]]);");
     }
 
+    @Test
+    public void testRefCount() {
+        assertEval("{ l <- list(a=c(1,2)); l2 <- l; l$a[[1]] <- 3; l2 }");
+    }
+
     @Test
     public void testList() {
         assertEval("{ list(a=1, b=2) }");
diff --git a/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/builtins/TestBuiltin_strsplit.java b/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/builtins/TestBuiltin_strsplit.java
index f508fdd27b6c4a938a5a8cf3c2c6e43f67cff2e3..f6d29dc8ce187711d5ca431f2ccac8c2555620b8 100644
--- a/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/builtins/TestBuiltin_strsplit.java
+++ b/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/builtins/TestBuiltin_strsplit.java
@@ -29,8 +29,7 @@ public class TestBuiltin_strsplit extends TestBase {
 
     @Test
     public void teststrsplit3() {
-        assertEval(Ignored.Unknown,
-                        "argv <- list('  \\036  isSeekable() now returns FALSE on connections       which have non-default encoding.  Although documented to       record if ‘in principle’ the connection supports seeking,       it seems safer to report FALSE when it may not work.', '[ \\t\\n]', FALSE, TRUE, FALSE); .Internal(strsplit(argv[[1]], argv[[2]], argv[[3]], argv[[4]], argv[[5]]))");
+        assertEval("argv <- list('  \\036  isSeekable() now returns FALSE on connections       which have non-default encoding.  Although documented to       record if ‘in principle’ the connection supports seeking,       it seems safer to report FALSE when it may not work.', '[ \\t\\n]', FALSE, TRUE, FALSE); .Internal(strsplit(argv[[1]], argv[[2]], argv[[3]], argv[[4]], argv[[5]]))");
     }
 
     @Test
@@ -121,5 +120,6 @@ public class TestBuiltin_strsplit extends TestBase {
         assertEval("strsplit('foo bar baz', '[f z]', perl=TRUE)");
         assertEval("strsplit('oo bar baz', '[f z]', perl=TRUE)");
         assertEval("strsplit('foo \u1010ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄbar baz ', '[f z]', perl=TRUE)");
+        assertEval("strsplit('Ä Ä', '[ ]', perl=TRUE)");
     }
 }
diff --git a/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/builtins/TestBuiltin_syscall.java b/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/builtins/TestBuiltin_syscall.java
index d080a5666e064ce1e05208b78ee7d615cd7f4d90..54d6ce721f9d5d609956d7a6427022ceaf546596 100644
--- a/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/builtins/TestBuiltin_syscall.java
+++ b/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/builtins/TestBuiltin_syscall.java
@@ -50,8 +50,8 @@ public class TestBuiltin_syscall extends TestBase {
         // these tests look a little weird as we seem to have some printing problems with language
         // objects (we should be able to simply print x, but the outputs don't quite match)
         assertEval("{ x<-do.call(function() sys.call(0), list()); x[[1]] }");
-        assertEval("{ x<-do.call(function() sys.call(1), list()); list(x[[1]], x[[2]][[1]], x[[2]][[2]], x[[2]][[3]]) }");
 
+        // whitespace in formatting of deparsed function
+        assertEval(Output.IgnoreWhitespace, "{ x<-(function(f) f())(function() sys.call(1)); list(x[[1]], x[[2]][[1]], x[[2]][[2]], x[[2]][[3]]) }");
     }
-
 }
diff --git a/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/builtins/TestBuiltin_unclass.java b/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/builtins/TestBuiltin_unclass.java
index df73382e61060130120eaf3ab39e07285da7f5eb..7dd8dbaa17e66d79719e805bcd25e3842af19f36 100644
--- a/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/builtins/TestBuiltin_unclass.java
+++ b/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/builtins/TestBuiltin_unclass.java
@@ -150,7 +150,7 @@ public class TestBuiltin_unclass extends TestBase {
 
     @Test
     public void testunclass26() {
-        assertEval(Ignored.Unknown, "argv <- list(structure(list(a = 1), .Dim = 1L, .Dimnames = list('a')));unclass(argv[[1]]);");
+        assertEval("argv <- list(structure(list(a = 1), .Dim = 1L, .Dimnames = list('a')));unclass(argv[[1]]);");
     }
 
     @Test
diff --git a/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/builtins/TestBuiltin_utf8ToInt.java b/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/builtins/TestBuiltin_utf8ToInt.java
index 02c42c7ce06ea4323842449050146f1cbe4ceba2..1f4d98fe1b3befb31dc6d1b78dda3382c92a1eed 100644
--- a/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/builtins/TestBuiltin_utf8ToInt.java
+++ b/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/builtins/TestBuiltin_utf8ToInt.java
@@ -17,13 +17,27 @@ import com.oracle.truffle.r.test.TestBase;
 // Checkstyle: stop line length check
 public class TestBuiltin_utf8ToInt extends TestBase {
 
+    @Test
+    public void testUtf8ToInt() {
+        assertEval("utf8ToInt('a')");
+        assertEval("utf8ToInt('Hello')");
+        assertEval("utf8ToInt('')");
+        assertEval("utf8ToInt(5)");
+        assertEval("utf8ToInt(character(0))");
+        assertEval("utf8ToInt(numeric(0))");
+        assertEval("utf8ToInt(NULL)");
+        assertEval("utf8ToInt(NA)");
+        assertEval(Output.IgnoreWhitespace, "utf8ToInt(c('a', 'b'))"); // no extra newline in
+                                                                       // warning msg
+    }
+
     @Test
     public void testutf8ToInt1() {
-        assertEval(Ignored.Unknown, "argv <- list('lasy'); .Internal(utf8ToInt(argv[[1]]))");
+        assertEval("argv <- list('lasy'); .Internal(utf8ToInt(argv[[1]]))");
     }
 
     @Test
     public void testutf8ToInt3() {
-        assertEval(Ignored.Unknown, "argv <- structure(list(x = NA_character_), .Names = 'x');do.call('utf8ToInt', argv)");
+        assertEval("argv <- structure(list(x = NA_character_), .Names = 'x');do.call('utf8ToInt', argv)");
     }
 }
diff --git a/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/builtins/TestBuiltin_warning.java b/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/builtins/TestBuiltin_warning.java
index 5a5983658c5f28085de17f339f515b5c38ebc13e..32105348fa57130763f66c036128cdf7a7b1df13 100644
--- a/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/builtins/TestBuiltin_warning.java
+++ b/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/builtins/TestBuiltin_warning.java
@@ -20,7 +20,7 @@ public class TestBuiltin_warning extends TestBase {
 
     @Test
     public void testwarning() {
-        assertEval("argv <- list('foo'); do.call('warning', argv)");
+        assertEval("warning('foo')");
         assertEval("f <- function() warning('foo'); f()");
         assertEval("f <- function() warning('foo'); f2 <- function() f(); f2()");
     }
diff --git a/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/builtins/TestBuiltin_zzfile.java b/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/builtins/TestBuiltin_zzfile.java
new file mode 100644
index 0000000000000000000000000000000000000000..b3db1793f86d90d0b93a8e558cda4078154e9e1b
--- /dev/null
+++ b/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/builtins/TestBuiltin_zzfile.java
@@ -0,0 +1,44 @@
+/*
+ * Copyright (c) 2016, 2016, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package com.oracle.truffle.r.test.builtins;
+
+import org.junit.Test;
+
+import com.oracle.truffle.r.test.TestBase;
+
+public class TestBuiltin_zzfile extends TestBase {
+    private static final String[] CTYPES = new String[]{"g", "b", "x"};
+
+    @Test
+    public void test1() {
+        assertEval(TestBase.template("{ f <- tempfile(); c <- %0zfile(f); writeLines(as.character(1:100), c); close(c); readLines(f) }", CTYPES));
+    }
+
+    @Test
+    public void test2() {
+        assertEval(TestBase.template(
+                        "{ f <- tempfile(); c <- %0zfile(f); writeLines(as.character(1:50), c); close(c); c <- %0zfile(f, \"a\"); writeLines(as.character(51:70), c); close(c); readLines(f) }",
+                        CTYPES));
+    }
+
+}
diff --git a/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/builtins/TestTestBase.java b/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/builtins/TestTestBase.java
new file mode 100644
index 0000000000000000000000000000000000000000..be53842774b8ccb73b1a0cdf99dc7a8322c0a420
--- /dev/null
+++ b/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/builtins/TestTestBase.java
@@ -0,0 +1,61 @@
+/*
+ * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package com.oracle.truffle.r.test.builtins;
+
+import org.junit.Ignore;
+import org.junit.Test;
+
+import com.oracle.truffle.r.test.TestBase;
+
+/**
+ * Documents and tests the testing API.
+ */
+public class TestTestBase extends TestBase {
+    @Test
+    public void testTraits() {
+        assertEval(Output.IgnoreErrorMessage, getCode("cat('Error in foo(42): FastR error message')", "cat('Error in foo(42): GnuR error message is different')"));
+        assertEval(Output.IgnoreErrorMessage, getCode("cat('Error in foo(44): IgnoreErrorMessage with different ctx')", "cat('Error in foo(42): IgnoreErrorMessage with different ctx')"));
+        assertEval(Output.IgnoreErrorMessage, getCode("cat('Error in foo(42): IgnoreErrorMessage starts with newline')", "cat('Error in foo(42):\\nIgnoreErrorMessage starts with newline')"));
+
+        assertEval(Output.IgnoreErrorContext, getCode("cat('Error in .Internal(foo(44)): IgnoreErrorContext')", "cat('Error in foo(42): IgnoreErrorContext')"));
+        assertEval(Output.IgnoreErrorContext, getCode("cat('Error in foo(42)   : IgnoreErrorContext extra spaces')", "cat('Error in foo(42): IgnoreErrorContext extra spaces')"));
+
+        assertEval(Output.IgnoreWarningContext, getCode("cat('Warning message: In .Internal(foo(42)) : IgnoreWarningContext')", "cat('Warning message: In foo(42) : IgnoreWarningContext')"));
+        assertEval(Output.IgnoreWarningContext,
+                        getCode("cat('Warning message: In .Internal(foo(42)) : IgnoreWarningContext extra newline')", "cat('Warning message: In foo(42) : \\nIgnoreWarningContext extra newline')"));
+
+        assertEval(Output.IgnoreWhitespace, getCode("cat('Error in foo(42) : IgnoreWhitespace extra spaces')", "cat('Error  in foo(42): \\nIgnoreWhitespace extra spaces')"));
+    }
+
+    @Test
+    @Ignore // these tests should fail
+    public void negativeTestTraits() {
+        assertEval(Output.IgnoreErrorContext, getCode("cat('Error in foo(44): IgnoreErrorContext diff message')", "cat('Error in foo(42): IgnoreErrorContext should fail')"));
+        assertEval(Output.IgnoreWarningContext,
+                        getCode("cat('Warning message: In .Internal(foo(42)): IgnoreWarningContext diff message')", "cat('Warning message in foo(42): IgnoreWarningContext should fail')"));
+    }
+
+    private static String getCode(String fastr, String gnur) {
+        return "if (exists('.fastr.identity')) { " + fastr + " } else { " + gnur + " }";
+    }
+}
diff --git a/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/generate/FastRSession.java b/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/generate/FastRSession.java
index 76f72535f078605530a079231a1041ea8b361629..8ec3a05b2b6e5ac59839441cfca49cbbaa7a4312 100644
--- a/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/generate/FastRSession.java
+++ b/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/generate/FastRSession.java
@@ -26,11 +26,12 @@ import java.util.ArrayDeque;
 import java.util.Arrays;
 import java.util.Deque;
 import java.util.TimeZone;
-import java.util.concurrent.Semaphore;
-import java.util.concurrent.TimeUnit;
-import java.util.concurrent.TimeoutException;
-
+import java.util.Timer;
+import java.util.TimerTask;
 import com.oracle.truffle.api.CompilerDirectives.TruffleBoundary;
+import com.oracle.truffle.api.debug.Debugger;
+import com.oracle.truffle.api.debug.SuspendedCallback;
+import com.oracle.truffle.api.debug.SuspendedEvent;
 import com.oracle.truffle.api.source.Source;
 import com.oracle.truffle.api.vm.PolyglotEngine;
 import com.oracle.truffle.r.runtime.RCmdOptions;
@@ -133,8 +134,6 @@ public final class FastRSession implements RSession {
     private final PolyglotEngine main;
     private final RContext mainContext;
 
-    private EvalThread evalThread;
-
     public static FastRSession create() {
         if (singleton == null) {
             singleton = new FastRSession();
@@ -191,143 +190,81 @@ public final class FastRSession implements RSession {
      * {@link #eval} but also used for package installation via the {@code system2} command, where
      * the result is used to check whether the installation succeeded.
      */
-    @SuppressWarnings("deprecation")
     public Object evalAsObject(TestBase testClass, String expression, ContextInfo contextInfo, boolean longTimeout) throws Throwable {
+        Object result = null;
+        Timer timer = null;
         consoleHandler.reset();
-        EvalThread thread = evalThread;
-        if (thread == null || !thread.isAlive() || contextInfo != thread.contextInfo) {
-            thread = new EvalThread(contextInfo);
-            thread.setName("FastR evaluation");
-            thread.start();
-            evalThread = thread;
-        }
-
-        thread.push(testClass, expression);
-
         try {
-            if (!thread.await(longTimeout ? longTimeoutValue : timeoutValue)) {
-                consoleHandler.println("<timeout>");
-                System.out.println("timeout in " + testClass.getClass() + ": " + expression);
-                for (StackTraceElement element : thread.getStackTrace()) {
-                    System.out.println(element);
-                }
-                thread.stop();
-                evalThread.ensureContextDestroyed();
-                evalThread = null;
-                throw new TimeoutException();
+            ContextInfo actualContextInfo = checkContext(contextInfo);
+            // set up some interop objects used by fastr-specific tests:
+            PolyglotEngine.Builder builder = PolyglotEngine.newBuilder();
+            if (testClass != null) {
+                testClass.addPolyglotSymbols(builder);
             }
-        } catch (InterruptedException e1) {
-            e1.printStackTrace();
-        }
-        if (thread.killedByException != null) {
-            evalThread = null;
-            throw thread.killedByException;
-        }
-        return evalThread.result;
-    }
-
-    private final class EvalThread extends RContext.ContextThread {
-
-        private volatile String expression;
-        private volatile Throwable killedByException;
-        private final Semaphore entry = new Semaphore(0);
-        private final Semaphore exit = new Semaphore(0);
-        private final ContextInfo contextInfo;
-        private TestBase testClass;
-        private Object result;
-
-        /**
-         * Create an evaluation thread (to handle timeouts).
-         *
-         * @param contextInfo {@code null} for a lightweight test context, else an existing one to
-         *            use.
-         */
-        EvalThread(ContextInfo contextInfo) {
-            super(null);
-            this.contextInfo = contextInfo;
-            setDaemon(true);
-        }
-
-        public void push(TestBase testClassArg, String exp) {
-            this.expression = exp;
-            this.testClass = testClassArg;
-            this.entry.release();
-        }
-
-        public boolean await(int millisTimeout) throws InterruptedException {
-            return exit.tryAcquire(millisTimeout, TimeUnit.MILLISECONDS);
-        }
-
-        /**
-         * In case the vm is not disposed by the {@code finally} clause in run after a timeout,
-         * (which should not happen), we explicitly destroy the context, to avoid subsequent errors
-         * relating to multiple children of a single SHARED_RW context.
-         */
-        public void ensureContextDestroyed() {
-            context.destroy();
-        }
-
-        @Override
-        public void run() {
-            while (killedByException == null) {
-                try {
-                    entry.acquire();
-                } catch (InterruptedException e) {
-                    break;
-                }
-                try {
-                    ContextInfo actualContextInfo = checkContext(contextInfo);
-                    // set up some interop objects used by fastr-specific tests:
-                    PolyglotEngine.Builder builder = PolyglotEngine.newBuilder();
-                    if (testClass != null) {
-                        testClass.addPolyglotSymbols(builder);
-                    }
-                    PolyglotEngine vm = actualContextInfo.createVM(builder);
-                    consoleHandler.setInput(expression.split("\n"));
+            PolyglotEngine vm = actualContextInfo.createVM(builder);
+            timer = scheduleTimeBoxing(vm, longTimeout ? longTimeoutValue : timeoutValue);
+            consoleHandler.setInput(expression.split("\n"));
+            try {
+                String input = consoleHandler.readLine();
+                while (input != null) {
+                    Source source = RSource.fromTextInternal(input, RSource.Internal.UNIT_TEST);
                     try {
-                        String input = consoleHandler.readLine();
-                        while (input != null) {
-                            Source source = RSource.fromTextInternal(input, RSource.Internal.UNIT_TEST);
-                            try {
-                                try {
-                                    result = vm.eval(source).get();
-                                    // checked exceptions are wrapped in RuntimeExceptions
-                                } catch (RuntimeException e) {
-                                    if (e.getCause() instanceof com.oracle.truffle.api.vm.IncompleteSourceException) {
-                                        throw e.getCause().getCause();
-                                    } else {
-                                        throw e;
-                                    }
-                                }
-                                input = consoleHandler.readLine();
-                            } catch (IncompleteSourceException e) {
-                                String additionalInput = consoleHandler.readLine();
-                                if (additionalInput == null) {
-                                    throw e;
-                                }
-                                input += "\n" + additionalInput;
+                        try {
+                            result = vm.eval(source).get();
+                            // checked exceptions are wrapped in RuntimeExceptions
+                        } catch (RuntimeException e) {
+                            if (e.getCause() instanceof com.oracle.truffle.api.vm.IncompleteSourceException) {
+                                throw e.getCause().getCause();
+                            } else {
+                                throw e;
                             }
                         }
-                    } finally {
-                        vm.dispose();
-                    }
-                } catch (ParseException e) {
-                    e.report(consoleHandler);
-                } catch (RError e) {
-                    // nothing to do
-                } catch (Throwable t) {
-                    if (!TestBase.ProcessFailedTests) {
-                        if (t instanceof RInternalError) {
-                            RInternalError.reportError(t);
+                        input = consoleHandler.readLine();
+                    } catch (IncompleteSourceException e) {
+                        String additionalInput = consoleHandler.readLine();
+                        if (additionalInput == null) {
+                            throw e;
                         }
-                        t.printStackTrace();
+                        input += "\n" + additionalInput;
                     }
-                    killedByException = t;
-                } finally {
-                    exit.release();
                 }
+            } finally {
+                vm.dispose();
+            }
+        } catch (ParseException e) {
+            e.report(consoleHandler);
+        } catch (RError e) {
+            // nothing to do
+        } catch (Throwable t) {
+            if (!TestBase.ProcessFailedTests) {
+                if (t instanceof RInternalError) {
+                    RInternalError.reportError(t);
+                }
+                t.printStackTrace();
+            }
+            throw t;
+        } finally {
+            if (timer != null) {
+                timer.cancel();
             }
         }
+        return result;
+    }
+
+    private static Timer scheduleTimeBoxing(PolyglotEngine engine, long timeout) {
+        Timer timer = new Timer();
+        timer.schedule(new TimerTask() {
+            @Override
+            public void run() {
+                Debugger.find(engine).startSession(new SuspendedCallback() {
+                    @Override
+                    public void onSuspend(SuspendedEvent event) {
+                        event.prepareKill();
+                    }
+                }).suspendNextExecution();
+            }
+        }, timeout);
+        return timer;
     }
 
     @Override
diff --git a/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/library/base/TestConditionHandling.java b/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/library/base/TestConditionHandling.java
index 938ca47fe03c098ecc428a49f5514d0877a01ebd..2aff030fb231737e9ef235ccda7fe76c4f3a44f8 100644
--- a/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/library/base/TestConditionHandling.java
+++ b/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/library/base/TestConditionHandling.java
@@ -32,8 +32,11 @@ public class TestConditionHandling extends TestBase {
     public void testTryCatch() {
         assertEval("{ tryCatch(1, finally = print(\"Hello\")) }");
         assertEval("{ e <- simpleError(\"test error\"); tryCatch(stop(e), finally = print(\"Hello\")) }");
+        assertEval("{ e <- simpleError(\"test error\"); f <- function() { tryCatch(1, finally = print(\"Hello\")); stop(e)}; f() }");
         assertEval(Output.IgnoreErrorContext, "{ tryCatch(stop(\"fred\"), finally = print(\"Hello\")) }");
         assertEval("{ e <- simpleError(\"test error\"); tryCatch(stop(e), error = function(e) e, finally = print(\"Hello\"))}");
         assertEval(Ignored.Unknown, "{ tryCatch(stop(\"fred\"), error = function(e) e, finally = print(\"Hello\"))}");
+        assertEval("{ f <- function() { tryCatch(1, error = function(e) print(\"Hello\")); stop(\"fred\")}; f() }");
+        assertEval("{ f <- function() { tryCatch(stop(\"fred\"), error = function(e) print(\"Hello\"))}; f() }");
     }
 }
diff --git a/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/library/fastr/TestInterop.java b/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/library/fastr/TestInterop.java
index 4633fbe6cea36712abcfa82e76de810cfd1160d8..2250149cb2075b762143b4d249ff3d3c5a5ddc6c 100644
--- a/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/library/fastr/TestInterop.java
+++ b/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/library/fastr/TestInterop.java
@@ -47,6 +47,14 @@ public class TestInterop extends TestBase {
         assertEvalFastR(".fastr.interop.export('foo', new.env())", "invisible()");
     }
 
+    @Test
+    public void testInteropEvalFile() {
+        assertEvalFastR("fileConn<-file(\"testScript.R\");writeLines(c(\"x<-c(1)\",\"cat(x)\"), fileConn);close(fileConn);.fastr.interop.evalFile(\"testScript.R\",\"application/x-r\")",
+                        "x<-c(1);cat(x)");
+        assertEvalFastR("fileConn<-file(\"testScript.R\");writeLines(c(\"x<-c(1)\",\"cat(x)\"), fileConn);close(fileConn);.fastr.interop.evalFile(\"testScript.R\")", "x<-c(1);cat(x)");
+        assertEvalFastR("tryCatch(.fastr.interop.evalFile(\"/a/b.R\"),  error = function(e) e$message)", "cat('[1] \"Error reading file: /a/b.R\"\\n')");
+    }
+
     /**
      * Used for testing interop functionality.
      */
diff --git a/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/library/stats/TestDistributions.java b/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/library/stats/TestDistributions.java
new file mode 100644
index 0000000000000000000000000000000000000000..b372e721801c039ad33509331914c61ad6b62b46
--- /dev/null
+++ b/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/library/stats/TestDistributions.java
@@ -0,0 +1,255 @@
+/*
+ * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package com.oracle.truffle.r.test.library.stats;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+
+import org.junit.Test;
+
+import com.oracle.truffle.r.test.TestBase;
+
+/**
+ * There are four R functions for each distribution function, in case of uniform distribution it is:
+ * punif, qunif, dunif and runif. The last one is tested in {@link TestRandGenerationFunctions}, the
+ * first three are tested here.
+ * <p>
+ * This test infrastructure uses some properties of those functions: each distribution has some
+ * parameters, e.g. uniform has 'min' and 'max', and those are used as parameters for all three --
+ * punif, qunif, dunif. First parameters for pxxx and dxxx always have the same meaning (quantiles).
+ * First parameter of qxxx is always probability or log(probability) if log.p=TRUE.
+ */
+public class TestDistributions extends TestBase {
+    private static final String[] BOOL_VALUES = new String[]{"T", "F"};
+    private static final String[] DEFAULT_Q = new String[]{"-Inf", "-0.42e-30", "0", "0.42e-30", "Inf", "NaN"};
+    private static final String PROBABILITIES = "c(0, 42e-80, 0.1, 0.5, 0.7, 1-42e-80, 1)";
+    private static final String[] ERROR_PROBABILITIES = new String[]{"Inf", "-Inf", "NaN", "-42", "-0.42e-38"};
+
+    // @formatter:off
+    /**
+     * For each distribution we define meaningful (to test) combinations of parameters. For each such
+     * combination we also define  a list of meaningful (to test) quantile values (first argument to
+     * pxxx, and dxxx R functions).
+     */
+    private static final DistrTest[] testCases = new DistrTest[]{
+            distr("unif").
+                    test("-3, 3.3", withDefaultQ("-3", "2", "3.3")),
+            distr("cauchy").
+                    // alpha < 0 => error
+                    test("0, -1", withQuantiles("0", "-1", "42")).
+                    test("-5, 5", withDefaultQ("-5", "42")).
+                    test("-0.01, 0.03", withQuantiles("0", "-1", "1", "0.42e-30")),
+            distr("norm").
+                    // sd <= 0 => error
+                    test("0, -1", withQuantiles("0")).
+                    test("0, 0", withDefaultQ("1")).
+                    test("4, 4", withQuantiles("4", "-100", "0")),
+            distr("gamma").
+                    addErrorParamValues("-1", "0").
+                    test("1, scale=2", withDefaultQ()).
+                    test("11e11, scale=23e-11", withQuantiles("900", "5000", "0")),
+            distr("beta").
+                    addErrorParamValues("-1", "0").
+                    test("0.5, 0.5", withDefaultQ()).
+                    test("2, 5", withDefaultQ("0.5")).
+                    test("6, 3", withQuantiles("0.6", "0.1", "42e-33")).
+                    test("0.1, 3", withDefaultQ("0.2")).
+                    // "p==0, q==0, p = Inf, q = Inf <==> treat as one- or two-point mass"
+                    test("0, Inf", withDefaultQ("0.5")).
+                    test("Inf, 0", withDefaultQ("0.6")).
+                    test("0, 0", withDefaultQ("0.4")),
+            distr("exp").
+                    addErrorParamValues("-1", "0").
+                    test("13e-20", withDefaultQ("10", "-10")).
+                    test("42", withDefaultQ("42")).
+                    test("42e123", withDefaultQ("33e123")),
+            // tests for nchisq, which is called in chisq when second param is not missing
+            distr("chisq").
+                    addErrorParamValues("-3", "0").
+                    test("1, 1", withDefaultQ("0.5", "2")).
+                    test("420, 4", withQuantiles("0.42e-10", "100", "13e10", "11e111")).
+                    test("0.13e-8, 1", withQuantiles("0.42e-10", "100", "13e10", "11e111")).
+                    test("1, 0.13e-8", withQuantiles("0.42e-10", "100", "13e10", "11e111")),
+            // tests of nbeta, which is called in beta when third param is not missing
+            distr("beta").
+                    addErrorParamValues("-4", "0").
+                    test("10, 15, 0", withDefaultQ("10", "15", "100")).
+                    test("7, 13, 3", withDefaultQ("10", "15", "100")).
+                    test("7, 11, 0.37e-10", withQuantiles("10", "15", "100")).
+                    test("7, 113e11, 1", withQuantiles("10", "15", "100")),
+            // tests of nf (non central F distribution)
+            distr("f").
+                    addErrorParamValues("-1", "0").
+                    test("5, 5, 5", withDefaultQ("1", "10", "44", "123")).
+                    test("5, 0.12e-10, 5", withDefaultQ("1", "10", "44", "123")).
+                    test("5, 6, 0.12e-10", withDefaultQ("1", "10", "44", "123")).
+                    test("0.12e-10, 6, 31e10", withDefaultQ("1", "10", "44", "123")),
+            // hyper-geometric: #white balls in urn, #black balls in urn, #drawn balls
+            distr("hyper").
+                    addErrorParamValues("-10", "0.3").
+                    test("7, 11, 4", withQuantiles("1", "2", "3", "4", "20", "12e12")).
+                    test("7e12, 11, 4", withQuantiles("1", "2", "3", "4", "20", "12e12")).
+                    test("11, 7e12, 7", withQuantiles("1", "2", "3", "7", "20", "12e12")).
+                    // more drawn balls then there is white
+                    test("7, 11, 12", withQuantiles("1", "2", "3", "4", "5", "6", "7", "8", "11", "20", "12e12")).
+                    // this should show non-integer warnings for quantiles
+                    test("5, 5, 5", withQuantiles("0.1", "-Inf", "Inf", "0.3e89")).
+                    // too many drawn balls: should be error
+                    test("3, 4, 10", withQuantiles("2"))
+    };
+    // @formatter:on
+
+    @Test
+    public void testDensityFunctions() {
+        for (DistrTest testCase : testCases) {
+            for (ParamsAndQuantiles paramsAndQ : testCase.paramsAndQuantiles) {
+                testDensityFunction("d" + testCase.name, paramsAndQ.params, paramsAndQ.quantiles);
+            }
+            testErrorParams("d" + testCase.name, testCase.paramsAndQuantiles.get(0).params, testCase.errorParamValues);
+        }
+    }
+
+    @Test
+    public void testDistributionFunctions() {
+        for (DistrTest testCase : testCases) {
+            for (ParamsAndQuantiles paramsAndQ : testCase.paramsAndQuantiles) {
+                testDistributionFunction("p" + testCase.name, paramsAndQ.params, paramsAndQ.quantiles);
+            }
+            testErrorParams("p" + testCase.name, testCase.paramsAndQuantiles.get(0).params, testCase.errorParamValues);
+        }
+    }
+
+    @Test
+    public void testQuantileFunctions() {
+        for (DistrTest testCase : testCases) {
+            String func = "q" + testCase.name;
+            for (ParamsAndQuantiles paramsAndQ : testCase.paramsAndQuantiles) {
+                testQuantileFunction(func, paramsAndQ.params, PROBABILITIES, "F");
+                testQuantileFunction(func, paramsAndQ.params, "log(" + PROBABILITIES + ")", "T");
+            }
+            String validParams = testCase.paramsAndQuantiles.get(0).params;
+            assertEval(Output.MayIgnoreWarningContext, template(func + "(%0, " + validParams + ")", ERROR_PROBABILITIES));
+            testErrorParams(func, validParams, testCase.errorParamValues);
+        }
+    }
+
+    private void testErrorParams(String func, String paramsTemplate, ArrayList<String> errorParamValues) {
+        String[] validParams = paramsTemplate.split(",");
+        for (int i = 0; i < validParams.length; i++) {
+            String[] newParams = Arrays.copyOf(validParams, validParams.length);
+            for (String errVal : errorParamValues) {
+                newParams[i] = errVal;
+                assertEval(Output.MayIgnoreWarningContext, func + "(0, " + String.join(", ", newParams) + ")");
+            }
+        }
+    }
+
+    private void testDensityFunction(String func, String params, String[] quantiles) {
+        // creates code like 'qunif(c(1, 2), -3, 3, log=%0)' where '-3,3' is params and
+        // 1, 2 are quantiles, template then creates two tests with %0=T and %0=F
+        String qVector = "c(" + String.join(", ", quantiles) + ")";
+        String code = func + "(" + qVector + ", " + params + ", log=%0)";
+        assertEval(Output.MayIgnoreWarningContext, template(code, BOOL_VALUES));
+    }
+
+    private void testDistributionFunction(String func, String params, String[] quantiles) {
+        String qVector = "c(" + String.join(", ", quantiles) + ")";
+        String code = func + "(" + qVector + ", " + params + ", lower.tail=%0, log.p=%1)";
+        assertEval(Output.MayIgnoreWarningContext, template(code, BOOL_VALUES, BOOL_VALUES));
+    }
+
+    private void testQuantileFunction(String func, String params, String probabilities, String logP) {
+        String code = func + "(" + probabilities + ", " + params + ", lower.tail=%0, log.p=" + logP + ")";
+        assertEval(Output.MayIgnoreWarningContext, template(code, BOOL_VALUES));
+    }
+
+    private static DistrTest distr(String name) {
+        return new DistrTest(name);
+    }
+
+    private static String[] withQuantiles(String... quantiles) {
+        return quantiles;
+    }
+
+    private static String[] withDefaultQ(String... quantiles) {
+        String[] result = Arrays.copyOf(quantiles, quantiles.length + DEFAULT_Q.length);
+        System.arraycopy(DEFAULT_Q, 0, result, quantiles.length, DEFAULT_Q.length);
+        return result;
+    }
+
+    /**
+     * Represents a collection of test parameters for testing a distribution with given
+     * {@link #name}.
+     */
+    private static final class DistrTest {
+        public final String name;
+        public final ArrayList<ParamsAndQuantiles> paramsAndQuantiles = new ArrayList<>();
+        private int paramsCount = -1;
+        /**
+         * Set of single R values that are supposed to produce error when used as any of the
+         * parameters.
+         */
+        public final ArrayList<String> errorParamValues = new ArrayList<>();
+
+        DistrTest(String name) {
+            this.name = name;
+            addErrorParamValues("-Inf", "Inf", "NaN");
+        }
+
+        public DistrTest test(String params, String[] quantiles) {
+            assert paramsCount == -1 || params.split(",").length == paramsCount : "different length of params for " + name;
+            paramsCount = params.split(",").length;
+            paramsAndQuantiles.add(new ParamsAndQuantiles(params, quantiles));
+            return this;
+        }
+
+        public DistrTest addErrorParamValues(String... values) {
+            errorParamValues.addAll(Arrays.asList(values));
+            return this;
+        }
+
+        /**
+         * Removes the predefined "error" values for parameters. These are so far always the same,
+         * but this method is here to make the API "complete". May be removed if all distributions
+         * already have tests and non of them needs it.
+         */
+        @SuppressWarnings("unused")
+        public DistrTest clearDefaultErrorParamValues() {
+            errorParamValues.clear();
+            return this;
+        }
+    }
+
+    /**
+     * A combination of params, e.g. "3, 10", with set of quantiles that should be tested with it.
+     */
+    private static final class ParamsAndQuantiles {
+        public final String params;
+        public final String[] quantiles;
+
+        ParamsAndQuantiles(String params, String[] quantiles) {
+            this.params = params;
+            this.quantiles = quantiles;
+        }
+    }
+}
diff --git a/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/library/stats/TestExternal_rnbinom.java b/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/library/stats/TestExternal_rnbinom.java
index c8385786a2adca7b6873fd5f998a489dbdc135a4..1da764331667df2230c83d2f9385eb8354099e25 100644
--- a/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/library/stats/TestExternal_rnbinom.java
+++ b/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/library/stats/TestExternal_rnbinom.java
@@ -32,6 +32,6 @@ public class TestExternal_rnbinom extends TestBase {
     public void testRbinomWithMu() {
         assertEval("set.seed(42); rnbinom(5, 1, mu=2)");
         // TODO: maybe problem with state variables, see RNbinomMu
-        assertEval(Ignored.Unimplemented, "set.seed(42); rnbinom(100, c(-1, 0, 1, 0.8, 10, NA, NaN, 1/0, -1/0), mu=c(-1, 0, 1, 0.8, 3, 10, NA, NaN, 1/0, -1/0))");
+        assertEval(Ignored.Unstable, "set.seed(42); rnbinom(100, c(-1, 0, 1, 0.8, 10, NA, NaN, 1/0, -1/0), mu=c(-1, 0, 1, 0.8, 3, 10, NA, NaN, 1/0, -1/0))");
     }
 }
diff --git a/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/library/stats/TestStatFunctions.java b/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/library/stats/TestStatFunctions.java
index d15b49dd4f2a0250212fd7abd5e035e24cb85ffc..ad81c967d41a23fa6514aaec8d01871e6d88fd57 100644
--- a/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/library/stats/TestStatFunctions.java
+++ b/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/library/stats/TestStatFunctions.java
@@ -30,7 +30,7 @@ import com.oracle.truffle.r.test.TestBase;
  * Common tests for functions implemented using {@code StatsFunctions} infrastructure.
  */
 public class TestStatFunctions extends TestBase {
-    private static final String[] FUNCTION3_1_NAMES = {"dgamma", "dbeta", "dcauchy", "dlnorm"};
+    private static final String[] FUNCTION3_1_NAMES = {"dlnorm", "dlogis"};
     private static final String[] FUNCTION3_1_PARAMS = {
                     "10, 10, 10, log=TRUE",
                     "3, 3, 3, log=FALSE",
@@ -46,7 +46,7 @@ public class TestStatFunctions extends TestBase {
         assertEval(Output.IgnoreWhitespace, template("set.seed(1); %0(%1)", FUNCTION3_1_NAMES, FUNCTION3_1_PARAMS));
     }
 
-    private static final String[] FUNCTION2_1_NAMES = {"dchisq", "dexp", "dgeom", "dpois", "dt"};
+    private static final String[] FUNCTION2_1_NAMES = {"dchisq", "dgeom", "dpois", "dt"};
     private static final String[] FUNCTION2_1_PARAMS = {
                     "10, 10, log=TRUE",
                     "3, 3, log=FALSE",
@@ -61,7 +61,7 @@ public class TestStatFunctions extends TestBase {
         assertEval(Output.IgnoreWhitespace, template("set.seed(1); %0(%1)", FUNCTION2_1_NAMES, FUNCTION2_1_PARAMS));
     }
 
-    private static final String[] FUNCTION2_2_NAMES = {"pchisq", "pexp", "qexp", "qgeom"};
+    private static final String[] FUNCTION2_2_NAMES = {"pchisq", "qgeom", "pgeom", "qt", "pt", "qpois", "ppois", "qchisq"};
     private static final String[] FUNCTION2_2_PARAMS = {
                     "0, 10",
                     "c(-1, 0, 0.2, 2), rep(c(-1, 0, 0.1, 0.9, 3), 4)",
@@ -80,7 +80,7 @@ public class TestStatFunctions extends TestBase {
         assertEval(Output.IgnoreWhitespace, template("set.seed(1); %0(%1)", FUNCTION2_2_NAMES, new String[]{"rep(c(1, 0, 0.1), 5), c(NA, 0, NaN, 1/0, -1/0)"}));
     }
 
-    private static final String[] FUNCTION3_2_NAMES = {"pbeta", "pcauchy", "qcauchy", "qlnorm", "plnorm"};
+    private static final String[] FUNCTION3_2_NAMES = {"qlnorm", "plnorm", "qbinom", "qlogis", "pf", "pbinom", "plogis", "qf"};
     private static final String[] FUNCTION3_2_PARAMS = {
                     "0, 10, 10",
                     "c(-1, 0, 0.2, 2), c(-1, 0, 0.1, 0.9, 3), rep(c(-1, 0, 1, 0.1, -0.1, 0.0001), 20)",
@@ -90,16 +90,17 @@ public class TestStatFunctions extends TestBase {
     @Test
     public void testFunctions32() {
         // first: the "normal params" with all the combinations of log.p and lower.tail
-        assertEval(Output.IgnoreWhitespace, template("set.seed(1); %0(%1, %2, %3)",
+        assertEval(Output.MayIgnoreWarningContext, template("set.seed(1); %0(%1, %2, %3)",
                         FUNCTION3_2_NAMES, FUNCTION3_2_PARAMS, new String[]{"lower.tail=TRUE", "lower.tail=FALSE"}, new String[]{"log.p=TRUE", "log.p=FALSE"}));
         // the error cases (where log.p nor lower.tail should make no difference)
         // first parameter wrong
-        assertEval(Output.IgnoreWarningContext,
+        assertEval(Output.MayIgnoreWarningContext,
                         template("set.seed(1); %0(%1)", FUNCTION3_2_NAMES, new String[]{"c(NA, 0, NaN, 1/0, -1/0), rep(c(1, 0, 0.1), 5), rep(c(1, 0, 0.1), 5)"}));
         // second parameter wrong
-        assertEval(Output.IgnoreWarningContext,
+        assertEval(Output.MayIgnoreWarningContext,
                         template("set.seed(1); %0(%1)", FUNCTION3_2_NAMES, new String[]{"rep(c(1, 0, 0.1), 5), c(NA, 0, NaN, 1/0, -1/0), rep(c(1, 0, 0.1), 5)"}));
         // third parameter wrong
-        assertEval(Output.IgnoreWhitespace, template("set.seed(1); %0(%1)", FUNCTION3_2_NAMES, new String[]{"rep(c(1, 0, 0.1), 5), rep(c(1, 0, 0.1), 5), c(NA, 0, NaN, 1/0, -1/0)"}));
+        assertEval(Output.MayIgnoreWarningContext,
+                        template("set.seed(1); %0(%1)", FUNCTION3_2_NAMES, new String[]{"rep(c(1, 0, 0.1), 5), rep(c(1, 0, 0.1), 5), c(NA, 0, NaN, 1/0, -1/0)"}));
     }
 }
diff --git a/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/rffi/TestRFFIPackage.java b/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/rffi/TestRFFIPackage.java
index 40270c5de51f4b35661184065b85a52780d0e742..400a9c7b8f90f0a833c0fa568b46212095152d8c 100644
--- a/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/rffi/TestRFFIPackage.java
+++ b/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/rffi/TestRFFIPackage.java
@@ -160,4 +160,9 @@ public class TestRFFIPackage extends TestRPackages {
     public void testRFFI19() {
         assertEvalWithLibWithSetup("x <- 1; ", "rffi.findvar(\"x\", globalenv())");
     }
+
+    @Test
+    public void testRFFI20() {
+        assertEvalWithLibWithSetup("x <- \"12345\"; ", "rffi.char_length(x)");
+    }
 }
diff --git a/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/tools/ShowLLVMIR.java b/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/tools/ShowLLVMIR.java
new file mode 100644
index 0000000000000000000000000000000000000000..bc21326e8681db7c6d2f512e8a1d739b6c6238d7
--- /dev/null
+++ b/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/tools/ShowLLVMIR.java
@@ -0,0 +1,132 @@
+/*
+ * Copyright (c) 2014, 2016, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package com.oracle.truffle.r.test.tools;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+import com.oracle.truffle.r.runtime.ProcessOutputManager;
+import com.oracle.truffle.r.runtime.ffi.truffle.LLVM_IR;
+
+public class ShowLLVMIR {
+    public static void main(String[] args) {
+        String objPath = null;
+        String llpart = null;
+        boolean list = false;
+        boolean xxports = false;
+        boolean dis = false;
+        int i = 0;
+        while (i < args.length) {
+            String arg = args[i];
+            switch (arg) {
+                case "-o":
+                    i++;
+                    objPath = args[i];
+                    break;
+                case "-ll":
+                case "--module":
+                    i++;
+                    llpart = args[i];
+                    break;
+                case "--names":
+                case "--list":
+                    list = true;
+                    break;
+                case "--xxports":
+                    xxports = true;
+                    break;
+                case "--dis":
+                    dis = true;
+                    break;
+
+            }
+            i++;
+        }
+        if (objPath == null) {
+            usage();
+        }
+        try {
+            LLVM_IR[] irs = LLVM_IR.getLLVMIR(objPath);
+            if (irs == null) {
+                System.out.printf("no llvm ir in %s\n", objPath);
+                System.exit(1);
+            }
+            for (LLVM_IR ir : irs) {
+                if (list) {
+                    System.out.println(ir.name);
+                } else {
+                    if (llpart == null || ir.name.equals(llpart)) {
+                        System.out.printf("Module: %s%n", ir.name);
+                        if (xxports) {
+                            System.out.println("Exports");
+                            System.out.println("=======");
+                            for (String export : ir.exports) {
+                                System.out.println(export);
+                            }
+                            System.out.println("Imports");
+                            System.out.println("=======");
+                            for (String importx : ir.imports) {
+                                System.out.println(importx);
+                            }
+                        }
+                        if (dis) {
+                            String text = null;
+                            if (ir instanceof LLVM_IR.Binary) {
+                                LLVM_IR.Binary irb = (LLVM_IR.Binary) ir;
+                                try {
+                                    ProcessBuilder pb = new ProcessBuilder("llvm-dis");
+                                    Process p = pb.start();
+                                    InputStream os = p.getInputStream();
+                                    OutputStream is = p.getOutputStream();
+                                    ProcessOutputManager.OutputThreadVariable readThread = new ProcessOutputManager.OutputThreadVariable("llvm-dis", os);
+                                    readThread.start();
+                                    is.write(irb.binary);
+                                    is.close();
+                                    @SuppressWarnings("unused")
+                                    int rc = p.waitFor();
+                                    text = new String(readThread.getData(), 0, readThread.getTotalRead());
+                                } catch (IOException ex) {
+                                    System.err.println(ex);
+                                    System.exit(2);
+                                }
+                            } else {
+                                LLVM_IR.Text tir = (LLVM_IR.Text) ir;
+                                text = tir.text;
+                            }
+                            System.out.println(text);
+                        }
+                    }
+                }
+            }
+        } catch (Exception e) {
+            System.err.println(e);
+        }
+
+    }
+
+    private static void usage() {
+        System.err.print("usage: -o objfile");
+        System.exit(1);
+    }
+
+}
diff --git a/documentation/.project b/documentation/.project
new file mode 100644
index 0000000000000000000000000000000000000000..ee59972c532bfb399fe17812dc2245fc53e05cae
--- /dev/null
+++ b/documentation/.project
@@ -0,0 +1,20 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<projectDescription>
+	<name>FastR Documentation</name>
+	<comment></comment>
+	<projects>
+		<project>mx</project>
+		<project>mx.graal</project>
+		<project>mx.jvmci</project>
+	</projects>
+	<buildSpec>
+		<buildCommand>
+			<name>org.python.pydev.PyDevBuilder</name>
+			<arguments>
+			</arguments>
+		</buildCommand>
+	</buildSpec>
+	<natures>
+		<nature>org.python.pydev.pythonNature</nature>
+	</natures>
+</projectDescription>
diff --git a/documentation/Index.md b/documentation/Index.md
index b771c0e5543b8b1ebd7266990ce40405688ea7a2..4b1d8167ed57b3d7fa7ceccaf4d414b4f0c59744 100644
--- a/documentation/Index.md
+++ b/documentation/Index.md
@@ -4,3 +4,4 @@
 
 [Limitations](Limitations.md)
 
+[For Developers](dev/Index.md)
diff --git a/documentation/dev/Index.md b/documentation/dev/Index.md
new file mode 100644
index 0000000000000000000000000000000000000000..3a1d4565e614411518d52a4666f0de5793374db0
--- /dev/null
+++ b/documentation/dev/Index.md
@@ -0,0 +1,10 @@
+# FastR Developer Documentation
+
+## Index
+
+* [Project Structure](structure.md)
+* [Building](building.md)
+* [R FFI Implementation](ffi.md)
+
+
+
diff --git a/documentation/dev/building.md b/documentation/dev/building.md
new file mode 100644
index 0000000000000000000000000000000000000000..7dc6f484022c78dd8f0c7998bce66ac2b10a096d
--- /dev/null
+++ b/documentation/dev/building.md
@@ -0,0 +1,27 @@
+# Introduction
+
+This section contains more information regarding the build process. The `mx build` command will build both the Java projects and the native projects.
+
+# Details on Building the Native Code
+
+## Building GNU R
+
+The `com.oracle.truffle.r.native/gnur` directory contains the `Makefile` for building GNU R in such a way that
+parts are reusable by FastR. The GNU R source code is download by
+
+It is a multi-step process to build GNU R in such a way that FASTR can use some of the libraries.
+After building GNU R we extract configuration information for use in building packages in the FastR environment.
+This goes into the file `platform.mk`, which is included in the `Makefile``s for the standard packages built for FastR.
+The main change is to define the symbol `FASTR` to ensure that some important modifications to `Rinternals.h` are made
+(e.g. changing a `SEXP` to a `void*`).
+
+## Building the Standard GNU R Packages
+
+This directory tree contains the default packages for FastR. Most packages contain native (C/Fortran) code that
+must be recompiled for FastR to ensure that the FFI calls are handled correctly. The regenerated `package.so` file overwrites
+the file in the `library/package/libs` directory; otherwise the directory contents are identical to GNU R.
+
+As far as possible the native recompilation reference the corresponding source files in the `com.oracle.truffle.r.native/gnur`
+directory. In a few case these files have to be modified but every attempt it made to avoid wholesale copy of GNU R source files.
+
+Note that `datasets` doesn`t actually have any native code, but it is convenient to store it here to mirror GNU R.
diff --git a/documentation/dev/ffi.md b/documentation/dev/ffi.md
new file mode 100644
index 0000000000000000000000000000000000000000..0be78c5bacccd8fc4563b4da07e17bf5c9c1c6a3
--- /dev/null
+++ b/documentation/dev/ffi.md
@@ -0,0 +1,54 @@
+# The R FFI Implementation
+
+# Introduction
+The implementation of the [R FFI](https://cran.r-project.org/doc/manuals/r-release/R-exts.html) is contained in the `fficall` directory of
+the `com.oracle/truffle.r.native` project`. It's actually a bit more than that as it also contains code copied from GNU R, for example that supports graphics or is sufficiently
+simple that it is neither necessary nor desirable to implement in Java. As this has evolved a better name for `fficall` would probably be `main`
+for compatibility with GNU R.
+
+ There are four sub-directories in `fficall/src`:
+ * `include`
+ * `common`
+ * `variable_defs`
+ * `jni`
+ * `truffle`
+
+## The `fficall/include` directory
+
+`include` should be thought as analgous to GNU R's `src/include`, i.e. internal headers needed by the code in `src/main`.
+What we are trying to do by redefining them here is provide a boundary so that we don`t accidently capture code from GNU R that
+is specific to the implementation of GNU R that is different in FastR, e.g., the representation of R objects. Evidently not every
+piece of GNU R code or an internal header has that characteristic but this strategy allows us some control to draw the boundary as
+tight as possible. Obviously we want to avoid duplicating (copying) code, as this requires validating the copy when migrating GNU R versions,
+so there are three levels of implementation choice for the content of the header in this directory:
+
+* Leave empty. This allows a `#include` to succeed and, if code does not actually use any symbols from the header, is ok.
+* Indirect to the real GNU R header. This is potentially dangerous but a simple default for code that uses symbols from the header.
+* Extract specific definitions from the GNU R header into a cut-down version. While this copies code it may be necessary to avoid unwanted aspects of the GNU R header. In principle this can be done by a "copy with sed" approach.
+
+The indirection requires the use of the quote form of the `#include` directive. To avoid using a path that is GNU R version dependent,
+the file ``gnurheaders.mk` provides a make variable `GNUR_HEADER_DEFS` with a set of appropriate -`D CFLAGS`.
+
+Ideally, code is always compiled in such a way that headers are never implicitly read from GNU R, only via the `include` directory.
+Unfortunately this cannot always be guaranteed as a directive of the form include "foo.h" (as opposed to include <foo.h>) in the
+GNU R C code will always access a header in the same directory as the code being compiled. I.e., only the angle-bracket form can be controlled
+by the `-I` compiler flag. If this is a problem, the only solution is to "copy with sed" the `.c` file and convert the quote form to the
+angle bracket form.
+
+## The `common` directory
+`common` contains code that has no explicit JNI dependencies and has been extracted for reuse in other implementations. This code is mostly
+copied/included from GNU R. N.B. Some modified files have a `_fastr` suffix to avoid a clash with an existing file in GNU R that would match
+the Makefile rule for compiling directly from the GNU R file.
+
+## The `variable_defs` directory
+
+The GNU R FFI defines a large number of (extern) variables the definitions of which, in GNU R, are scattered across the source files.
+In FastR these are collected into one file, `variable_defs.h`. However, the actual initialization of the variables is, in general, implementation
+dependent. In order to support a JNI and a non-JNI implementation, the file is stored in a separate directory.
+
+## The `jni` directory
+`jni` contains the implementation that is based on and has explicit dependencies on Java JNI. It is described in more detail [here](jni_ffi.md)
+
+## The `truffle` directory
+
+`truffle` contains the native side of the variant that is based on the Truffle LLVM implementation. It is described in more detail [here](truffle_ffi.md)
\ No newline at end of file
diff --git a/documentation/dev/jni_ffi.md b/documentation/dev/jni_ffi.md
new file mode 100644
index 0000000000000000000000000000000000000000..f2fa26e388a4fb408e57a3257eda77132a1c739d
--- /dev/null
+++ b/documentation/dev/jni_ffi.md
@@ -0,0 +1,17 @@
+# Introduction
+The R FFI is rather baroque and defined in large set of header files in the `include` directory that is a sibling of `fficall`.
+In GNU R, the implementation of the functions is spread over the GNU R C files in `src/main`. To ease navigation of the FastR implementation,
+in general, the implementation of the functions in a header file `Rxxx.h` is stored in the file `Rxxx.c`.
+
+The points of entry from Java are defined in the file `rfficall.c`. Various utility functions are defined in `rffiutils.{h,c}`.
+
+## JNI References
+
+Java object values are passed to native code using JNI local references that are valid for the duration of the call. The reference protects the object from garbage collection. Evidently if native code holds on to a local reference by storing it in a native variable,
+that object might be collected, possibly causing incorrect behavior (at best) later in the execution. It is possible to convert a local reference to a global reference that preserves the object across multiple JNI calls but this risks preventing objects from being collected. The global variables defined in the R FFI, e.g. `R_NilValue` are necessarily handled as global references. Other values are left as local references, with some risk that native code might capture a value that would then be collected once the call completes.
+
+## Vector Content Copying
+
+The R FFI provides access to vector contents as raw C pointers, e.g., `int *`. This requires the use of the JNI functions to access/copy the underlying data. In addition it requires  that multiple calls on the same SEXP always return the same raw pointer.
+Similar to the discussion on JNI references, the raw data is released at the end of the call. There is currently no provision to retain this data across multiple JNI calls.
+
diff --git a/documentation/dev/structure.md b/documentation/dev/structure.md
new file mode 100644
index 0000000000000000000000000000000000000000..14851e3135302b44714efffc1b7cb2495c0a476f
--- /dev/null
+++ b/documentation/dev/structure.md
@@ -0,0 +1,11 @@
+# Introduction
+
+The FastR codebase is structured around IDE `projects`, which are contained in directories beginning with `com.oracle.truffle.r`.
+The expectation is that source code will be viewed and edited in an IDE (we will use Eclipse as the example) and the `mx` tool
+has support for automatically generating the IDE project metadata via the `ideinit` command. N.B. if you run this before you have built the system with `mx build`
+do not be surprised that it will compile some Java classes. It does this to gather information about Java annotation processors that is necessary for
+correct rebuilding within the IDE.
+
+The majority of the projects are "Java" projects, but any project with `native` in its name contains native code, e.g. C code, and is (ultimately) built
+using `make`. `mx` handles this transparently. Note, however, that editing and building the native code in an IDE requires support for C development to have
+been installed. E.g. for Eclipse, the CDE plugin.
diff --git a/documentation/dev/truffle_ffi.md b/documentation/dev/truffle_ffi.md
new file mode 100644
index 0000000000000000000000000000000000000000..8eb7fd13ca344734107b2a70c0e9a4a9ce37aae1
--- /dev/null
+++ b/documentation/dev/truffle_ffi.md
@@ -0,0 +1,63 @@
+# Introduction
+
+The Truffle implementation of the R FFI is based on the Truffle implementation of LLVM intermediate code, named [Sulong](https://github.com/graalvm/sulong).
+
+
+# Building
+Special setup is required to build FastR to use the Truffle R FFI implementation.
+
+## Building Sulong
+The `sulong` repository must be cloned to a sibling directory of `fastr` and built:
+
+    cd $FASTR_HOME
+    git clone https://github.com/graalvm/sulong.git
+    cd sulong
+    mx build
+    mx su-pulldragonegg
+
+The `mx build` step will clone the `graal-core` repository, if necessary, and build that also. The `mx su-pulldragonegg` step is required to be able to compile Fortran code to LLVM, which is required by FastR.
+
+## Additional Pre-Requisites
+
+The DragonEgg plugin requires that `gcc 4.6` and `gfortran 4.6` be available. On Mac OS, these can be installed with MacPorts (recommended) or Brew. Having installed these, set the following environment variables:
+
+    export SULONG_GPP=/opt/local/bin/g++-mp-4.6
+    export SULONG_GFORTRAN=/opt/local/bin/gfortran-mp-4.6
+    export SULONG_GCC=/opt/local/bin/gcc-mp-4.6
+
+The above definitions assume a MacPorts installation.
+
+Both GNU R and FastR native code must be compiled to generate LLVM code. This is handled by special "wrapper" compiler scripts that encapsulate the required steps.
+To ensure that the wrapper compiler scripts are used in the GNU R build set:
+
+    export FASTR_TRUFFLE_RFFI=true
+
+If you have an existing build, you must unset any definition of `GNUR_NOCLEAN` then run `mx build -c`. The wrapper scripts add quite a bit of overhead to the build process, particularly the GNU R configure step, but fortunately this only has to be done once.
+
+## Running
+
+There is no compile-time dependency between FastR and Sulong; all communication is via the Truffle Interop API. Therefore Sulong must be dynamically imported using either `mx --dynamicimport sulong` or by setting the environment variable `DEFAULT_DYNAMIC_IMPORTS=sulong`, with latter being most convenient. With this in effect, a normal `mx R` will make SuLong available. In particular, the factory class that controls which FFI implementation is in used is chosen based on whether Sulong is available.
+
+Even then, by default, the Truffle FFI implementation is not enabled and the system defaults to the normal JNI RFFI implementation, in order to support an
+incremental approach to enabling native code for LLVM implementation. To enable one or more packages (strictly their associated dynamic libraries) for LLVM implementation, set the environment variable `FASTR_TRUFFLE_LIBS` to a comma-separated list of library names, e.g. `stats,testrffi`. If this variable is unset,and the Truffle RFFI factory class is enabled, a warning is given on every library open that the load is defaulting to the JNI implementation.
+
+At the time of writing, only the following libraries have been tested in LLVM mode:
+
+* `liburand`: this is not actually a package library, but a test for the user-defined random number generator feature of R. It lives in the
+`com.oracle.truffle.r.test.native/urand` directory and must be loaded explicitly using `dyn.load`. See the `TestUserRNG` class for an example of how to test it.
+* `testrffi`: This is the (evolving) RFFI test package that lives in `com.oracle.truffle.r.test.native/packages/testrffi`. It must first be installed by e.g, `bin/R CMD INSTALL com.oracle.truffle.r.test.native/packages/testrffi/lib/testrffi.tar`. As always this will install to the location specified by the `R_LIBS_USER` or `R_LIBS` environment variables or, if unset, the FastR `library` directory. An example test would then be to execute `library(testrffi); rffi.addDouble(2,3)` after running `mx R`.
+* `stats`: Most of the native code in the GNU R `stats` package has either been rewritten in Java or temporarily disabled. However, the Fast Fourier Transform code is written in C and called through the FFI. E.g. `fft(1:4)` is a simple test.
+* `digest`: This is a CRAN package that contains a significant amount of native code, relating to MD5 and SHA digest generation. The simple way to install and test this is to execute: `mx pkgtest '^digest$'`. This assumes an internet connection is available to access CRAN.
+
+Note that if the `LLVM_PARSE_TIME` environment variable is set to any value, the time taken to parse each LLVM module is logged to the console, which is also an indication that the LLVM implementation variant is being used.
+
+# Implementation Details
+
+## Compiler Wrapper Scripts
+
+The compiler wrapper scripts are simple shell scripts that first test for the existence of the `sulong` sibling directory and, if it exists and the environment variable `FASTR_SULONG_IGNORE` is not set, invoke associated `mx` commands to perform the compilation. Otherwise, the standard compiler is used. The scripts are stored in the `compilers` sub-directory of `mx.fastr` and are named: `fastr-cc`, `fastr-fc`, `fastr-c++` and `fastr-cpp`. The associated `mx` commands are in `mx.fastr/mx_fastr_compilers.py`.
+
+In order to support both LLVM and non-LLVM execution, each native source file is compiled twice, once to generate native machine code and once to generate LLVM IR. The LLVM IR is actually stored in the object file and extracted at runtime. This avoids having to disrupt the normal R package build process by allowing it to be completely unaware of the existence of LLVM.
+
+Currently, for convenience, the Python wrappers invoke code in the Sulong `sulong/mx.sulong` directory. Eventually, they will modified to be independent of Sulong.
+
diff --git a/mx.fastr/compilers/fastr-c++ b/mx.fastr/compilers/fastr-c++
new file mode 100755
index 0000000000000000000000000000000000000000..2d8cc481f9b9a50c0d6225a4e6b66c52525e7707
--- /dev/null
+++ b/mx.fastr/compilers/fastr-c++
@@ -0,0 +1,47 @@
+#
+# Copyright (c) 2016, 2016, Oracle and/or its affiliates. All rights reserved.
+# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+#
+# This code is free software; you can redistribute it and/or modify it
+# under the terms of the GNU General Public License version 2 only, as
+# published by the Free Software Foundation.
+#
+# This code is distributed in the hope that it will be useful, but WITHOUT
+# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+# FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+# version 2 for more details (a copy is included in the LICENSE file that
+# accompanied this code).
+#
+# You should have received a copy of the GNU General Public License version
+# 2 along with this work; if not, write to the Free Software Foundation,
+# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+#
+# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+# or visit www.oracle.com if you need additional information or have any
+# questions.
+#
+#!/bin/bash
+
+SOURCE="${BASH_SOURCE[0]}"
+while [ -h "$SOURCE" ]; do
+  DIR="$( cd -P "$( dirname "$SOURCE" )" && pwd )"
+  SOURCE="$(readlink "$SOURCE")"
+  [[ $SOURCE != /* ]] && SOURCE="$DIR/$SOURCE"
+done
+DIR="$( cd -P "$( dirname "$SOURCE" )" && pwd )"
+
+with_sulong=0
+while [ $DIR != "/" ] ; do
+  if [ -d $DIR/sulong ] && [ -d $DIR/sulong/mx.sulong ] ; then
+    with_sulong=1
+    break
+  fi
+  DIR=`dirname $DIR`
+done
+
+if [ $with_sulong = 1 ] && [ "$FASTR_SULONG_IGNORE" = "" ] ; then
+    mx --dynamicimport sulong fastr-c++ $@
+else
+    g++ $@
+fi
+
diff --git a/mx.fastr/compilers/fastr-cc b/mx.fastr/compilers/fastr-cc
new file mode 100755
index 0000000000000000000000000000000000000000..ff05a0f750e2aea46665b44880480462d2d443c0
--- /dev/null
+++ b/mx.fastr/compilers/fastr-cc
@@ -0,0 +1,47 @@
+#
+# Copyright (c) 2016, 2016, Oracle and/or its affiliates. All rights reserved.
+# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+#
+# This code is free software; you can redistribute it and/or modify it
+# under the terms of the GNU General Public License version 2 only, as
+# published by the Free Software Foundation.
+#
+# This code is distributed in the hope that it will be useful, but WITHOUT
+# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+# FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+# version 2 for more details (a copy is included in the LICENSE file that
+# accompanied this code).
+#
+# You should have received a copy of the GNU General Public License version
+# 2 along with this work; if not, write to the Free Software Foundation,
+# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+#
+# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+# or visit www.oracle.com if you need additional information or have any
+# questions.
+#
+#!/bin/bash
+
+SOURCE="${BASH_SOURCE[0]}"
+while [ -h "$SOURCE" ]; do
+  DIR="$( cd -P "$( dirname "$SOURCE" )" && pwd )"
+  SOURCE="$(readlink "$SOURCE")"
+  [[ $SOURCE != /* ]] && SOURCE="$DIR/$SOURCE"
+done
+DIR="$( cd -P "$( dirname "$SOURCE" )" && pwd )"
+
+with_sulong=0
+while [ $DIR != "/" ] ; do
+  if [ -d $DIR/sulong ] && [ -d $DIR/sulong/mx.sulong ] ; then
+    with_sulong=1
+    break
+  fi
+  DIR=`dirname $DIR`
+done
+
+if [ $with_sulong = 1 ] && [ "$FASTR_SULONG_IGNORE" = "" ] ; then
+	mx --dynamicimport sulong fastr-cc $@
+else
+    gcc $@
+fi
+
diff --git a/mx.fastr/compilers/fastr-cpp b/mx.fastr/compilers/fastr-cpp
new file mode 100755
index 0000000000000000000000000000000000000000..5e5a24e6cc91d91f5ca7c67efcfb65904417366e
--- /dev/null
+++ b/mx.fastr/compilers/fastr-cpp
@@ -0,0 +1,46 @@
+#
+# Copyright (c) 2016, 2016, Oracle and/or its affiliates. All rights reserved.
+# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+#
+# This code is free software; you can redistribute it and/or modify it
+# under the terms of the GNU General Public License version 2 only, as
+# published by the Free Software Foundation.
+#
+# This code is distributed in the hope that it will be useful, but WITHOUT
+# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+# FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+# version 2 for more details (a copy is included in the LICENSE file that
+# accompanied this code).
+#
+# You should have received a copy of the GNU General Public License version
+# 2 along with this work; if not, write to the Free Software Foundation,
+# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+#
+# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+# or visit www.oracle.com if you need additional information or have any
+# questions.
+#
+#!/bin/bash
+
+SOURCE="${BASH_SOURCE[0]}"
+while [ -h "$SOURCE" ]; do
+  DIR="$( cd -P "$( dirname "$SOURCE" )" && pwd )"
+  SOURCE="$(readlink "$SOURCE")"
+  [[ $SOURCE != /* ]] && SOURCE="$DIR/$SOURCE"
+done
+DIR="$( cd -P "$( dirname "$SOURCE" )" && pwd )"
+
+with_sulong=0
+while [ $DIR != "/" ] ; do
+  if [ -d $DIR/sulong ] && [ -d $DIR/sulong/mx.sulong ] ; then
+    with_sulong=1
+    break
+  fi
+  DIR=`dirname $DIR`
+done
+
+if [ $with_sulong = 1 ] && [ "$FASTR_SULONG_IGNORE" = "" ] ; then
+	mx --dynamicimport sulong fastr-cpp $@
+else
+    cpp $@
+fi
diff --git a/mx.fastr/compilers/fastr-fc b/mx.fastr/compilers/fastr-fc
new file mode 100755
index 0000000000000000000000000000000000000000..e5f506854e54513bd3dacbe95f94690dfd99fce3
--- /dev/null
+++ b/mx.fastr/compilers/fastr-fc
@@ -0,0 +1,47 @@
+#
+# Copyright (c) 2016, 2016, Oracle and/or its affiliates. All rights reserved.
+# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+#
+# This code is free software; you can redistribute it and/or modify it
+# under the terms of the GNU General Public License version 2 only, as
+# published by the Free Software Foundation.
+#
+# This code is distributed in the hope that it will be useful, but WITHOUT
+# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+# FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+# version 2 for more details (a copy is included in the LICENSE file that
+# accompanied this code).
+#
+# You should have received a copy of the GNU General Public License version
+# 2 along with this work; if not, write to the Free Software Foundation,
+# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+#
+# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+# or visit www.oracle.com if you need additional information or have any
+# questions.
+#
+#!/bin/bash
+
+SOURCE="${BASH_SOURCE[0]}"
+while [ -h "$SOURCE" ]; do
+  DIR="$( cd -P "$( dirname "$SOURCE" )" && pwd )"
+  SOURCE="$(readlink "$SOURCE")"
+  [[ $SOURCE != /* ]] && SOURCE="$DIR/$SOURCE"
+done
+DIR="$( cd -P "$( dirname "$SOURCE" )" && pwd )"
+
+with_sulong=0
+while [ $DIR != "/" ] ; do
+  if [ -d $DIR/sulong ] && [ -d $DIR/sulong/mx.sulong ] ; then
+    with_sulong=1
+    break
+  fi
+  DIR=`dirname $DIR`
+done
+
+if [ $with_sulong = 1 ] && [ "$FASTR_SULONG_IGNORE" = "" ] ; then
+    mx --dynamicimport sulong fastr-fc $@
+else
+    gfortran $@
+fi
+
diff --git a/mx.fastr/compilers/have_sulong b/mx.fastr/compilers/have_sulong
new file mode 100755
index 0000000000000000000000000000000000000000..a650e87c518dd7362aaf94bb3ae25ab69aad2bd0
--- /dev/null
+++ b/mx.fastr/compilers/have_sulong
@@ -0,0 +1,46 @@
+#
+# Copyright (c) 2016, 2016, Oracle and/or its affiliates. All rights reserved.
+# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+#
+# This code is free software; you can redistribute it and/or modify it
+# under the terms of the GNU General Public License version 2 only, as
+# published by the Free Software Foundation.
+#
+# This code is distributed in the hope that it will be useful, but WITHOUT
+# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+# FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+# version 2 for more details (a copy is included in the LICENSE file that
+# accompanied this code).
+#
+# You should have received a copy of the GNU General Public License version
+# 2 along with this work; if not, write to the Free Software Foundation,
+# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+#
+# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+# or visit www.oracle.com if you need additional information or have any
+# questions.
+#
+#!/bin/bash
+
+SOURCE="${BASH_SOURCE[0]}"
+while [ -h "$SOURCE" ]; do # resolve $SOURCE until the file is no longer a symlink
+  DIR="$( cd -P "$( dirname "$SOURCE" )" && pwd )"
+  SOURCE="$(readlink "$SOURCE")"
+  [[ $SOURCE != /* ]] && SOURCE="$DIR/$SOURCE" # if $SOURCE was a relative symlink, we need to resolve it relative to the path where the symlink file was located
+done
+DIR="$( cd -P "$( dirname "$SOURCE" )" && pwd )"
+
+with_sulong=0
+while [ $DIR != "/" ] ; do
+  if [ -d $DIR/sulong ] && [ -d $DIR/sulong/mx.sulong ] ; then
+    with_sulong=1
+    break
+  fi
+  DIR=`dirname $DIR`
+done
+
+if [ $with_sulong = 1 ] && [ "$FASTR_SULONG_IGNORE" = "" ] ; then
+  echo "yes"
+else
+  echo "no"
+fi
diff --git a/mx.fastr/copyrights/gnu_r.core.copyright.star.regex b/mx.fastr/copyrights/gnu_r.core.copyright.star.regex
index e625a25f307693d9872191aad9ce88e5fab49ef1..f2659e583f63f8a67d0e648f9c07248211e150c1 100644
--- a/mx.fastr/copyrights/gnu_r.core.copyright.star.regex
+++ b/mx.fastr/copyrights/gnu_r.core.copyright.star.regex
@@ -1 +1 @@
-/\*\n \* This material is distributed under the GNU General Public License\n \* Version 2. You may review the terms of this license at\n \* http://www.gnu.org/licenses/gpl-2.0.html\n \*\n \* Copyright \(c\) (?:[1-2][09][0-9][0-9]--)?[1-2][09][0-9][0-9], The R Core Team\n \* Copyright \(c\) (?:(20[0-9][0-9]), )?(20[0-9][0-9]), Oracle and/or its affiliates\n \*\n \* All rights reserved.\n \*/\n.*
\ No newline at end of file
+/\*\n \* This material is distributed under the GNU General Public License\n \* Version 2. You may review the terms of this license at\n \* http://www.gnu.org/licenses/gpl-2.0.html\n \*\n \* Copyright \(c\) (?:[1-2][09][0-9][0-9]--?)?(:?[1-2][09])?[0-9]?[0-9], The R Core Team\n \* Copyright \(c\) (?:(20[0-9][0-9]), )?(20[0-9][0-9]), Oracle and/or its affiliates\n \*\n \* All rights reserved.\n \*/\n.*
diff --git a/mx.fastr/copyrights/gnu_r_ihaka.copyright.star.regex b/mx.fastr/copyrights/gnu_r_ihaka.copyright.star.regex
index f501f18d94af207fdf7bdb31d6ed504d3fe2713b..53c1d8c22ec45e849999d5d42177053b6a70a3f3 100644
--- a/mx.fastr/copyrights/gnu_r_ihaka.copyright.star.regex
+++ b/mx.fastr/copyrights/gnu_r_ihaka.copyright.star.regex
@@ -1 +1 @@
-/\*\n \* This material is distributed under the GNU General Public License\n \* Version 2. You may review the terms of this license at\n \* http://www.gnu.org/licenses/gpl-2.0.html\n \*\n \* Copyright \(C\) 1998 Ross Ihaka\n \* Copyright \(c\) (?:[1-2][09][0-9][0-9]--)?[1-2][09][0-9][0-9], The R Core Team\n \* Copyright \(c\) (?:[1-2][09][0-9][0-9]--)?[1-2][09][0-9][0-9], The R Foundation\n \* Copyright \(c\) (?:(20[0-9][0-9]), )?(20[0-9][0-9]), Oracle and/or its affiliates\n \*\n \* All rights reserved.\n \*/\n.*
+/\*\n \* This material is distributed under the GNU General Public License\n \* Version 2. You may review the terms of this license at\n \* http://www.gnu.org/licenses/gpl-2.0.html\n \*\n \* Copyright \(C\) 1998 Ross Ihaka\n \* Copyright \(c\) (?:[1-2][09][0-9][0-9]--?)?(?:[1-2][09])?[0-9][0-9], The R Core Team\n \* Copyright \(c\) (?:[1-2][09][0-9][0-9]--?)?(?:[1-2][09])?[0-9][0-9], The R Foundation\n \* Copyright \(c\) (?:(20[0-9][0-9]), )?(20[0-9][0-9]), Oracle and/or its affiliates\n \*\n \* All rights reserved.\n \*/\n.*
diff --git a/mx.fastr/copyrights/gnu_r_ihaka_core.copyright.star.regex b/mx.fastr/copyrights/gnu_r_ihaka_core.copyright.star.regex
index f6aa3d2ffea7b64fd737bf54fc193fdb726a58e0..8ede89dd35f94ed03a8536f0e424da12c89a727e 100644
--- a/mx.fastr/copyrights/gnu_r_ihaka_core.copyright.star.regex
+++ b/mx.fastr/copyrights/gnu_r_ihaka_core.copyright.star.regex
@@ -1 +1 @@
-/\*\n \* This material is distributed under the GNU General Public License\n \* Version 2. You may review the terms of this license at\n \* http://www.gnu.org/licenses/gpl-2.0.html\n \*\n \* Copyright \(C\) 1998 Ross Ihaka\n \* Copyright \(c\) (?:[1-2][09][0-9][0-9]--)?[1-2][09][0-9][0-9], The R Core Team\n \* Copyright \(c\) (?:(20[0-9][0-9]), )?(20[0-9][0-9]), Oracle and/or its affiliates\n \*\n \* All rights reserved.\n \*/\n.*
+/\*\n \* This material is distributed under the GNU General Public License\n \* Version 2. You may review the terms of this license at\n \* http://www.gnu.org/licenses/gpl-2.0.html\n \*\n \* Copyright \(C\) 1998 Ross Ihaka\n \* Copyright \(c\) (?:[1-2][09][0-9][0-9]--?)?(?:[1-2][09])?[0-9][0-9], The R Core Team\n \* Copyright \(c\) (?:(20[0-9][0-9]), )?(20[0-9][0-9]), Oracle and/or its affiliates\n \*\n \* All rights reserved.\n \*/\n.*
diff --git a/mx.fastr/copyrights/gnu_r_scan.copyright.star.regex b/mx.fastr/copyrights/gnu_r_scan.copyright.star.regex
index b8d748ad4e6d7a169aac923745c54b9e21dc5801..a2b6bd808f74cf4378eede05500ff8c8420bbe94 100644
--- a/mx.fastr/copyrights/gnu_r_scan.copyright.star.regex
+++ b/mx.fastr/copyrights/gnu_r_scan.copyright.star.regex
@@ -1 +1 @@
-/\*\n \* This material is distributed under the GNU General Public License\n \* Version 2. You may review the terms of this license at\n \* http://www.gnu.org/licenses/gpl-2.0.html\n \*\n \* Copyright \(c\) 1995, 1996, Robert Gentleman and Ross Ihaka\n \* Copyright \(c\) 1998-2013, The R Core Team\n \* Copyright \(c\) (?:(20[0-9][0-9]), )?(20[0-9][0-9]), Oracle and/or its affiliates\n \*\n \* All rights reserved.\n \*/\n.*
+/\*\n \* This material is distributed under the GNU General Public License\n \* Version 2. You may review the terms of this license at\n \* http://www.gnu.org/licenses/gpl-2.0.html\n \*\n \* Copyright \(c\) 1995, 1996, Robert Gentleman and Ross Ihaka\n \* Copyright \(c\) (?:[1-2][09][0-9][0-9]--?)?[1-2][09][0-9][0-9], The R Core Team\n \* Copyright \(c\) (?:(20[0-9][0-9]), )?(20[0-9][0-9]), Oracle and/or its affiliates\n \*\n \* All rights reserved.\n \*/\n.*
diff --git a/mx.fastr/copyrights/gnu_r_welinder.copyright.star b/mx.fastr/copyrights/gnu_r_welinder.copyright.star
new file mode 100644
index 0000000000000000000000000000000000000000..7010e84df1c5295dd8ce7ab2459deb0e3a87ddfe
--- /dev/null
+++ b/mx.fastr/copyrights/gnu_r_welinder.copyright.star
@@ -0,0 +1,12 @@
+/*
+ * This material is distributed under the GNU General Public License
+ * Version 2. You may review the terms of this license at
+ * http://www.gnu.org/licenses/gpl-2.0.html
+ *
+ * Copyright (C) 2005-6 Morten Welinder <terra@gnome.org>
+ * Copyright (C) 2005-10 The R Foundation
+ * Copyright (C) 2006-2015 The R Core Team
+ * Copyright (c) 2015, Oracle and/or its affiliates
+ *
+ * All rights reserved.
+ */
diff --git a/mx.fastr/copyrights/gnu_r_welinder.copyright.star.regex b/mx.fastr/copyrights/gnu_r_welinder.copyright.star.regex
new file mode 100644
index 0000000000000000000000000000000000000000..19cd6eb6374ecbb028949b5395c404d87987bd7e
--- /dev/null
+++ b/mx.fastr/copyrights/gnu_r_welinder.copyright.star.regex
@@ -0,0 +1 @@
+/\*\n \* This material is distributed under the GNU General Public License\n \* Version 2. You may review the terms of this license at\n \* http://www.gnu.org/licenses/gpl-2.0.html\n \*\n \* Copyright \([cC]\) (?:[1-2][09][0-9][0-9]--?)?([1-2][09][0-9])?[0-9] Morten Welinder <terra@gnome.org>\n \* Copyright \([cC]\) (?:[1-2][09][0-9][0-9]--?)?([1-2][09])?[0-9]?[0-9] The R Foundation\n \* Copyright \([cC]\) (?:[1-2][09][0-9][0-9]--?)?[1-2][09][0-9][0-9] The R Core Team\n \* Copyright \([cC]\) (?:(20[0-9][0-9]), )?(20[0-9][0-9]), Oracle and/or its affiliates\n \*\n \* All rights reserved.\n \*/\n.*
diff --git a/mx.fastr/copyrights/overrides b/mx.fastr/copyrights/overrides
index 0467373d319614885a7468b7ad3c4ddd3c190853..1e88b6c8693d9058247af6629a2e3e753ef8afb8 100644
--- a/mx.fastr/copyrights/overrides
+++ b/mx.fastr/copyrights/overrides
@@ -29,6 +29,7 @@ com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/grid/GridFunctions
 com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/methods/MethodsListDispatch.java,gnu_r.copyright
 com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/methods/Slot.java,gnu_r.copyright
 com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/stats/Arithmetic.java,gnu_r_gentleman_ihaka.copyright
+com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/stats/DNorm.java,gnu_r.copyright
 com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/stats/RBeta.java,gnu_r_gentleman_ihaka.copyright
 com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/stats/RMultinom.java,gnu_r_gentleman_ihaka.copyright
 com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/stats/Cauchy.java,gnu_r_ihaka_core.copyright
@@ -43,34 +44,53 @@ com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/stats/DPQ.java,gnu
 com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/stats/Rt.java,gnu_r_ihaka_core.copyright
 com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/stats/GammaFunctions.java,gnu_r_qgamma.copyright
 com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/stats/QHyper.java,gnu_r_ihaka_core.copyright
+com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/stats/DHyper.java,gnu_r.core.copyright
+com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/stats/PHyper.java,gnu_r_ihaka.copyright
+com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/stats/Qt.java,gnu_r_ihaka.copyright
+com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/stats/Pt.java,gnu_r_scan.copyright
 com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/stats/RHyper.java,gnu_r_ihaka.copyright
 com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/stats/MathInit.java,gnu_r.core.copyright
 com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/stats/Pbeta.java,gnu_r.core.copyright
+com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/stats/PNBeta.java,gnu_r.core.copyright
+com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/stats/QNBeta.java,gnu_r.core.copyright
+com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/stats/Qnf.java,gnu_r.core.copyright
+com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/stats/Dnf.java,gnu_r.core.copyright
+com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/stats/DNBeta.java,gnu_r_ihaka_core.copyright
 com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/stats/LBeta.java,gnu_r_ihaka.copyright
 com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/stats/Pbinom.java,gnu_r_ihaka.copyright
 com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/stats/Pf.java,gnu_r_ihaka_core.copyright
 com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/stats/Pnorm.java,gnu_r_ihaka.copyright
+com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/stats/PPois.java,gnu_r_ihaka_core.copyright
+com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/stats/QPois.java,gnu_r_ihaka_core.copyright
+com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/stats/QBeta.java,gnu_r_scan.copyright
+com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/stats/Qf.java,gnu_r_ihaka.copyright
 com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/stats/Qbinom.java,gnu_r_ihaka.copyright
 com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/stats/Qnorm.java,gnu_r_ihaka.copyright
 com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/stats/Random2.java,gnu_r.copyright
 com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/stats/RPois.java,gnu_r_ihaka_core.copyright
 com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/stats/Rbinom.java,gnu_r_ihaka.copyright
+com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/stats/Unif.java,gnu_r_ihaka_core.copyright
 com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/stats/Rnorm.java,gnu_r.copyright
 com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/stats/Chisq.java,gnu_r_ihaka_core.copyright
+com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/stats/PNChisq.java,gnu_r.copyright
+com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/stats/QNChisq.java,gnu_r_gentleman_ihaka.copyright
+com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/stats/DNChisq.java,gnu_r_ihaka.copyright
 com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/stats/SplineFunctions.java,gnu_r_splines.copyright
 com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/stats/StatsFunctions.java,gnu_r_gentleman_ihaka.copyright
 com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/stats/RandGenerationFunctions.java,gnu_r_gentleman_ihaka.copyright
 com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/stats/RMath.java,gnu_r_ihaka.copyright
+com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/stats/RMathError.java,gnu_r.core.copyright
 com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/stats/LogNormal.java,gnu_r_ihaka.copyright
 com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/stats/MathConstants.java,gnu_r_ihaka.copyright
 com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/stats/TOMS708.java,gnu_r.copyright
 com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/stats/SNorm.java,gnu_r_ihaka_core.copyright
 com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/stats/SExp.java,gnu_r_ihaka_core.copyright
 com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/stats/RGamma.java,gnu_r_ihaka_core.copyright
+com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/stats/PGamma.java,gnu_r_welinder.copyright
 com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/stats/RNbinomMu.java,gnu_r_ihaka_core.copyright
-com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/stats/RLogis.java,gnu_r_ihaka_core.copyright
+com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/stats/Logis.java,gnu_r_ihaka_core.copyright
+com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/stats/Pnf.java,gnu_r_ihaka_core.copyright
 com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/stats/Rf.java,gnu_r_ihaka_core.copyright
-com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/stats/RChisq.java,gnu_r_ihaka_core.copyright
 com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/stats/Exp.java,gnu_r_ihaka_core.copyright
 com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/stats/Geom.java,gnu_r_ihaka_core.copyright
 com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/stats/Dt.java,gnu_r.core.copyright
@@ -110,6 +130,7 @@ com.oracle.truffle.r.native/fficall/src/variable_defs/variable_defs.h,gnu_r.copy
 com.oracle.truffle.r.native/fficall/src/jni/Memory.c,gnu_r.copyright
 com.oracle.truffle.r.native/fficall/src/jni/pcre_rffi.c,gnu_r_gentleman_ihaka2.copyright
 com.oracle.truffle.r.native/fficall/src/jni/Rdynload_fastr.c,gnu_r.copyright
+com.oracle.truffle.r.native/fficall/src/truffle/Rdynload_fastr.c,gnu_r.copyright
 com.oracle.truffle.r.native/fficall/src/jni/Rembedded.c,gnu_r.copyright
 com.oracle.truffle.r.native/include/src/libintl.h,no.copyright
 com.oracle.truffle.r.native/library/base/src/registration.c,no.copyright
@@ -163,7 +184,6 @@ com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/f
 com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/foreign/CallAndExternalFunctions.java,gnu_r.copyright
 com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/foreign/MakeQuartzDefault.java,gnu_r.copyright
 com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/foreign/ReadTableHead.java,gnu_r.copyright
-com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/foreign/Dnorm4.java,gnu_r.copyright
 com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/Format.java,gnu_r.copyright
 com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/FormatC.java,gnu_r.copyright
 com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/GetClass.java,purdue.copyright
@@ -242,6 +262,7 @@ com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/RRuntime.java,gnu_
 com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/RSerialize.java,gnu_r.copyright
 com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/RType.java,gnu_r.copyright
 com.oracle.truffle.r.test.native/urand/src/urand.c,gnu_r.copyright
+com.oracle.truffle.r.test.native/urand/src/nrand.c,gnu_r.copyright
 com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/builtins/TestBuiltin_abbreviate.java,purdue.copyright
 com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/builtins/TestBuiltin_abs.java,purdue.copyright
 com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/builtins/TestBuiltin_acos.java,purdue.copyright
diff --git a/mx.fastr/mx_fastr.py b/mx.fastr/mx_fastr.py
index 6815ab54d6de730e1afd12291a18fd8c4ddde57f..ceb60cfc4e9cc5d0762a9ce96540781d77bad0aa 100644
--- a/mx.fastr/mx_fastr.py
+++ b/mx.fastr/mx_fastr.py
@@ -26,6 +26,7 @@ from argparse import ArgumentParser
 import mx
 import mx_gate
 import mx_fastr_pkgs
+import mx_fastr_compile
 import mx_fastr_dists
 import mx_fastr_junit
 from mx_fastr_dists import FastRNativeProject, FastRTestNativeProject, FastRReleaseProject, FastRNativeRecommendedProject #pylint: disable=unused-import
@@ -47,6 +48,7 @@ _fastr_suite = mx.suite('fastr')
 If this is None, then we run under the standard VM in interpreted mode only.
 '''
 _mx_graal = mx.suite("graal-core", fatalIfMissing=False)
+_mx_sulong = mx.suite("sulong", fatalIfMissing=False)
 
 _r_command_package = 'com.oracle.truffle.r.engine'
 _repl_command = 'com.oracle.truffle.tools.debug.shell.client.SimpleREPLClient'
@@ -91,9 +93,14 @@ def do_run_r(args, command, extraVmArgs=None, jdk=None, **kwargs):
     if not jdk:
         jdk = get_default_jdk()
 
-    vmArgs = mx.get_runtime_jvm_args('FASTR', jdk=jdk)
+    dists = ['FASTR']
+    if _mx_sulong:
+        dists.append('SULONG')
+
+    vmArgs = mx.get_runtime_jvm_args(dists, jdk=jdk)
 
     vmArgs += set_graal_options()
+    vmArgs += _sulong_options()
 
     if extraVmArgs is None or not '-da' in extraVmArgs:
         # unless explicitly disabled we enable assertion checking
@@ -142,6 +149,13 @@ def set_graal_options():
     else:
         return []
 
+def _sulong_options():
+    if _mx_sulong:
+        return ['-Dfastr.ffi.factory.class=com.oracle.truffle.r.engine.interop.ffi.Truffle_RFFIFactory',
+                '-XX:-UseJVMCIClassLoader']
+    else:
+        return []
+
 def _get_ldpaths(env, lib_env_name):
     ldpaths = os.path.join(env['R_HOME'], 'etc', 'ldpaths')
     command = ['bash', '-c', 'source ' + ldpaths + ' && env']
@@ -347,6 +361,7 @@ def _junit_r_harness(args, vmArgs, jdk, junitArgs):
     vmArgs += ['-Xss12m']
     # no point in printing errors to file when running tests (that contain errors on purpose)
     vmArgs += ['-DR:-PrintErrorStacktracesToFile']
+    vmArgs += _sulong_options()
 
     setREnvironment()
 
@@ -586,4 +601,5 @@ _commands = {
     'nativebuild' : [nativebuild, '[]'],
     }
 
+_commands.update(mx_fastr_compile._commands)
 mx.update_commands(_fastr_suite, _commands)
diff --git a/mx.fastr/mx_fastr_compile.py b/mx.fastr/mx_fastr_compile.py
new file mode 100644
index 0000000000000000000000000000000000000000..701f3c2a5f7689543111444151572e3865128520
--- /dev/null
+++ b/mx.fastr/mx_fastr_compile.py
@@ -0,0 +1,343 @@
+#
+# Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved.
+# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+#
+# This code is free software; you can redistribute it and/or modify it
+# under the terms of the GNU General Public License version 2 only, as
+# published by the Free Software Foundation.
+#
+# This code is distributed in the hope that it will be useful, but WITHOUT
+# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+# FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+# version 2 for more details (a copy is included in the LICENSE file that
+# accompanied this code).
+#
+# You should have received a copy of the GNU General Public License version
+# 2 along with this work; if not, write to the Free Software Foundation,
+# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+#
+# Please 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 wrapper for the C/C++/Fortran compilers that optionally handles the generation of LLVM bitcode.
+When not running with sulong is simply forwards to the default compiler for the platform.
+When running under sulong, it uses sulong to do two compilations; first to generate object code
+and second to generate LLVM bitcode.
+"""
+import os, sys
+import mx
+import mx_fastr
+
+def _sulong():
+    sulong = mx.suite('sulong', fatalIfMissing=False)
+    if sulong:
+        return sulong.extensions
+    else:
+        return None
+
+def _is_linux():
+    return sys.platform.startswith('linux')
+
+def _is_darwin():
+    return sys.platform.startswith('darwin')
+
+def _log(cmd, args):
+    if os.environ.has_key('FASTR_COMPILE_LOGFILE'):
+        with open(os.environ['FASTR_COMPILE_LOGFILE'], 'a') as f:
+            f.write(cmd)
+            f.write('(')
+            f.write(os.getcwd())
+            f.write(')')
+            f.write(' ')
+            f.write(' '.join(args))
+            f.write('\n')
+
+class AnalyzedArgs:
+    '''
+    is_link: True iff the command is a shared library link
+    llvm_ir_file: the target file for the ir derived from the .o file (only set if is_link=False)
+    compile_args: possibly modified args for C compilation
+    emit_llvm_args: the args to generate the llvm ir
+    '''
+    def __init__(self, llvm_ir_file, is_link, compile_args, emit_llvm_args):
+        self.llvm_ir_file = llvm_ir_file
+        self.is_link = is_link
+        self.compile_args = compile_args
+        self.emit_llvm_args = emit_llvm_args
+
+
+def _c_dummy_file():
+    return os.path.join(mx_fastr._fastr_suite.dir, 'com.oracle.truffle.r.native', 'fficall', 'src', 'truffle', 'llvm_dummy.c')
+
+def _analyze_args(args, dragonEgg=False):
+    '''
+    Analyzes the original arguments to the compiler and returns an adjusted
+    list that will run the compiler (via sulong) to extract the llvm ir.
+    Result is an instance of AnalyzedArgs:
+    '''
+    compile_args = []
+    emit_llvm_args = []
+    llvm_ir_file_ext = '.bc'
+    if not dragonEgg:
+        emit_llvm_args.append('-emit-llvm')
+    else:
+        # dragonEgg plugin doesn't seem able to make bitcode directly
+        emit_llvm_args.append('-S')
+        llvm_ir_file_ext = '.ll'
+
+    is_link = False
+    llvm_ir_file = None
+    c_dummy = False
+    i = 0
+    while i < len(args):
+        arg = args[i]
+        if arg == '-DFASTR_LLVM':
+            c_dummy = True
+            i = i + 1
+            continue
+
+        emit_llvm_args.append(arg)
+        compile_args.append(arg)
+        if arg == '-c':
+            cfile = args[i + 1]
+            if c_dummy:
+                cfile = _c_dummy_file()
+            compile_args.append(cfile)
+            emit_llvm_args.append(args[i + 1])
+            i = i + 1
+
+        if arg == '-o':
+            ext = os.path.splitext(args[i + 1])[1]
+            is_link = ext == '.so' or ext == '.dylib'
+            compile_args.append(args[i + 1])
+            if ext == '.o':
+                llvm_ir_file = os.path.splitext(args[i + 1])[0] + llvm_ir_file_ext
+                emit_llvm_args.append(llvm_ir_file)
+            i = i + 1
+
+        i = i + 1
+    _log('adjusted-compile-args', compile_args)
+    _log('emit-llvm-args', emit_llvm_args)
+    return AnalyzedArgs(llvm_ir_file, is_link, compile_args, emit_llvm_args)
+
+def cc(args):
+    _log('fastr:cc', args)
+    compiler = None
+    sulong = _sulong()
+    if sulong:
+        analyzed_args = _analyze_args(args)
+        if _is_linux():
+            rc = sulong.compileWithGCC(analyzed_args.compile_args)
+            if rc == 0 and analyzed_args.llvm_ir_file:
+                if not analyzed_args.is_link:
+                    rc = sulong.compileWithGCC(analyzed_args.emit_llvm_args)
+        elif _is_darwin():
+            rc = sulong.compileWithClang(analyzed_args.compile_args)
+            if rc == 0 and analyzed_args.llvm_ir_file:
+                if not analyzed_args.is_link:
+                    rc = sulong.compileWithClang(analyzed_args.emit_llvm_args)
+        else:
+            mx.abort('unsupported platform')
+        if rc == 0 and not analyzed_args.is_link and analyzed_args.llvm_ir_file:
+            rc = _mem2reg_opt(analyzed_args.llvm_ir_file)
+            if rc == 0:
+                rc = _embed_ir(analyzed_args.llvm_ir_file)
+    else:
+        if _is_linux():
+            compiler = 'gcc'
+        elif _is_darwin():
+            compiler = 'clang'
+        else:
+            mx.abort('unsupported platform')
+
+        rc = mx.run([compiler] + args, nonZeroIsFatal=False)
+
+    return rc
+
+def fc(args):
+    _log('fastr:fc', args)
+    compiler = None
+    sulong = _sulong()
+    if sulong:
+        analyzed_args = _analyze_args(args, dragonEgg=True)
+        rc = mx.run([sulong.getGFortran()] + analyzed_args.compile_args, nonZeroIsFatal=False)
+        if rc == 0:
+            rc = sulong.dragonEggGFortran(analyzed_args.emit_llvm_args)
+            if rc == 0 and analyzed_args.llvm_ir_file:
+                # create bitcode from textual IR
+                llvm_as = sulong.findLLVMProgram('llvm-as')
+                llvm_bc_file = os.path.splitext(analyzed_args.llvm_ir_file)[0] + '.bc'
+                rc = mx.run([llvm_as, analyzed_args.llvm_ir_file, '-o', llvm_bc_file])
+                rc = _embed_ir(llvm_bc_file)
+    else:
+        compiler = 'gfortran'
+        rc = mx.run([compiler] + args, nonZeroIsFatal=False)
+
+    return rc
+
+def cpp(args):
+    _log('fastr:c++', args)
+    compiler = None
+    sulong = _sulong()
+    if sulong:
+        analyzed_args = _analyze_args(args)
+        if _is_linux():
+            rc = sulong.dragonEggGPP(analyzed_args.compile_args)
+        elif _is_darwin():
+            rc = sulong.compileWithClangPP(analyzed_args.compile_args)
+            if rc == 0:
+                if analyzed_args.llvm_ir_file:
+                    rc = sulong.compileWithClangPP(analyzed_args.emit_llvm_args)
+        else:
+            mx.abort('unsupported platform')
+        if rc == 0 and not analyzed_args.is_link:
+            rc = _embed_ir(analyzed_args.llvm_ir_file)
+    else:
+        compiler = 'g++'
+        rc = mx.run([compiler] + args, nonZeroIsFatal=False)
+
+    return rc
+
+def cppcpp(args):
+    '''C++ pre-preprocessor'''
+    _log('fastr:cpp', args)
+    rc = mx.run(['cpp'] + args)
+    return rc
+
+def _mem2reg_opt(llvm_ir_file):
+    filename = os.path.splitext(llvm_ir_file)[0]
+    ext = os.path.splitext(llvm_ir_file)[1]
+    opt_filename = filename + '.opt' + ext
+    rc = _sulong().opt(['-mem2reg', llvm_ir_file, '-o', opt_filename])
+    if rc == 0:
+        os.rename(opt_filename, llvm_ir_file)
+    return rc
+
+def _embed_ir(llvm_ir_file):
+    '''
+    Given an llvm_ir_file, generates an assembler file containing the content as a sequence
+    of .byte directives, then uses ld to merge that with the original .o file, replacing
+    the original .o file.
+    '''
+
+    def write_hexbyte(f, b):
+        f.write("0x%0.2X" % b)
+
+    def write_int(f, n):
+        write_hexbyte(f, n & 255)
+        f.write(',')
+        write_hexbyte(f, (n >> 8) & 255)
+        f.write(',')
+        write_hexbyte(f, (n >> 16) & 255)
+        f.write(',')
+        write_hexbyte(f, (n >> 24) & 255)
+
+    def write_symbol(f, sym):
+        write_dot_byte(f)
+        write_hexbyte(f, len(sym))
+        f.write(', ')
+        first = True
+        for ch in sym:
+            if first:
+                first = False
+            else:
+                f.write(', ')
+            write_hexbyte(f, ord(ch))
+        f.write('\n')
+
+    def write_dot_byte(f):
+        f.write('        .byte ')
+
+    def checkchars(s):
+        return s.replace("-", "_")
+
+    # find the exported symbols
+    llvm_nm = _sulong().findLLVMProgram("llvm-nm")
+
+    class NMOutputCapture:
+        def __init__(self):
+            self.exports = []
+            self.imports = []
+
+        def __call__(self, data):
+            # T name
+            s = data.strip()
+            if s[0] == 'T':
+                self.exports.append(s[2:])
+            elif s[0] == 'U':
+                self.imports.append(s[2:])
+
+    llvm_nm_out = NMOutputCapture()
+    mx.run([llvm_nm, llvm_ir_file], out=llvm_nm_out)
+
+    with open(llvm_ir_file) as f:
+        content = bytearray(f.read())
+    filename = os.path.splitext(llvm_ir_file)[0]
+    ext = os.path.splitext(llvm_ir_file)[1]
+    as_file = llvm_ir_file + '.s'
+    gsym = "__llvm_" + checkchars(os.path.basename(filename))
+    with open(as_file, 'w') as f:
+        f.write('        .const\n')
+        f.write('        .globl ' + gsym + '\n')
+        f.write(gsym + ':\n')
+        count = 0
+        lenc = len(content)
+        write_dot_byte(f)
+        # 1 for text, 2 for binary, followed by length
+        write_hexbyte(f, 1 if ext == '.ll' else 2)
+        f.write(',')
+        write_int(f, lenc)
+        f.write('\n')
+        # now the exported symbols
+        write_dot_byte(f)
+        write_int(f, len(llvm_nm_out.exports))
+        f.write('\n')
+        for sym in llvm_nm_out.exports:
+            write_symbol(f, sym)
+        # now the imported symbols
+        write_dot_byte(f)
+        write_int(f, len(llvm_nm_out.imports))
+        f.write('\n')
+        for sym in llvm_nm_out.imports:
+            write_symbol(f, sym)
+        # now the content
+        write_dot_byte(f)
+        first = True
+        for b in content:
+            if first:
+                first = False
+            else:
+                f.write(',')
+            write_hexbyte(f, b)
+            count = count + 1
+            if count % 20 == 0 and count < lenc:
+                f.write('\n')
+                write_dot_byte(f)
+                first = True
+        f.write('\n')
+
+    ll_o_file = llvm_ir_file + '.o'
+    rc = mx.run(['gcc', '-c', as_file, '-o', ll_o_file], nonZeroIsFatal=False)
+    if rc == 0:
+        # combine
+        o_file = filename + '.o'
+        dot_o_file = o_file + '.o'
+        os.rename(o_file, dot_o_file)
+        rc = mx.run(['ld', '-r', dot_o_file, ll_o_file, '-o', o_file], nonZeroIsFatal=False)
+        os.remove(dot_o_file)
+        os.remove(as_file)
+        os.remove(ll_o_file)
+    return rc
+
+def mem2reg(args):
+    _mem2reg_opt(args[0])
+
+_commands = {
+    'fastr-cc' : [cc, '[options]'],
+    'fastr-fc' : [fc, '[options]'],
+    'fastr-c++' : [cpp, '[options]'],
+    'fastr-cpp' : [cppcpp, '[options]'],
+    'mem2reg' : [mem2reg, '[options]'],
+}
diff --git a/mx.fastr/suite.py b/mx.fastr/suite.py
index 4003efe2cde967c8fb499814c73639ad8a24837c..3bde24d972d2b00ced260ed4ecc68e2bd96ab7a7 100644
--- a/mx.fastr/suite.py
+++ b/mx.fastr/suite.py
@@ -28,7 +28,7 @@ suite = {
     "suites" : [
             {
                "name" : "truffle",
-               "version" : "13641c9f68eefccd0099d283ca25d6bb44b3349a",
+               "version" : "720bba917bc2907b9e6620365a1b3c66e2ad3cc6",
                "urls" : [
                     {"url" : "https://github.com/graalvm/truffle", "kind" : "git"},
                     {"url" : "https://curio.ssw.jku.at/nexus/content/repositories/snapshots", "kind" : "binary"},
@@ -90,6 +90,12 @@ suite = {
       "sha1" : "ebb4b995fd67a9b291ea5b19379509160f56e154",
     },
 
+    "XZ-1.5" : {
+      "path" : "libdownloads/xz-1.5.jar",
+      "urls" : ["http://central.maven.org/maven2/org/tukaani/xz/1.5/xz-1.5.jar"],
+      "sha1" : "9c64274b7dbb65288237216e3fae7877fd3f2bee",
+    },
+
   },
 
   "projects" : {
@@ -210,6 +216,7 @@ suite = {
       "dependencies" : [
         "truffle:TRUFFLE_API",
         "truffle:TRUFFLE_DEBUG",
+        "XZ-1.5",
       ],
       "checkstyle" : "com.oracle.truffle.r.runtime",
       "javaCompliance" : "1.8",
@@ -304,6 +311,7 @@ suite = {
         "ANTLR-3.5",
         "GNUR",
         "GNU_ICONV",
+        "XZ-1.5",
       ],
       "distDependencies" : [
         "truffle:TRUFFLE_API",