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 7c28a860b7c2c9158abd41f07e4360f1753f3d26..bdad479b98efd9546b467c40cfb17ba753dc7e19 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
@@ -167,7 +167,7 @@ public abstract class GammaFunctions {
     private static final double xbig = 94906265.62425156;
     private static final double lgc_xmax = 3.745194030963158e306;
 
-    private static double lgammacor(double x) {
+    static double lgammacor(double x) {
         double tmp;
 
         if (x < 10) {
@@ -183,6 +183,10 @@ public abstract class GammaFunctions {
         return 1 / (x * 12);
     }
 
+    static double lgamma(double x) {
+        throw RError.nyi(RError.SHOW_CALLER, "lgamma from libc");
+    }
+
     //
     // gammafn
     //
@@ -211,7 +215,7 @@ public abstract class GammaFunctions {
 
     private static final double M_LN_SQRT_2PI = 0.918938533204672741780329736406;
 
-    private static double gammafn(double x) {
+    static double gammafn(double x) {
         int i;
         int n;
         double y;
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
new file mode 100644
index 0000000000000000000000000000000000000000..6cc0de5a33d977f8dec7d56bf66456d975a15ee3
--- /dev/null
+++ b/com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/stats/LBeta.java
@@ -0,0 +1,66 @@
+/*
+ * 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--2012, The R Core Team
+ * Copyright (c) 2003, 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.gammafn;
+import static com.oracle.truffle.r.library.stats.GammaFunctions.lgamma;
+import static com.oracle.truffle.r.library.stats.GammaFunctions.lgammacor;
+import static com.oracle.truffle.r.library.stats.GammaFunctions.lgammafn;
+import static com.oracle.truffle.r.library.stats.MathConstants.M_LN_SQRT_2PI;
+
+public final class LBeta {
+    public static double lbeta(double a, double b) {
+        double corr;
+        double p;
+        double q;
+
+        if (Double.isNaN(a) || Double.isNaN(b)) {
+            return a + b;
+        }
+
+        p = q = a;
+        if (b < p) {
+            p = b;
+            /* := min(a,b) */ }
+        if (b > q) {
+            q = b;
+            /* := max(a,b) */ }
+
+        /* both arguments must be >= 0 */
+        if (p < 0) {
+            return StatsUtil.mlError();
+        } else if (p == 0) {
+            return Double.POSITIVE_INFINITY;
+        } else if (!Double.isFinite(q)) { /* q == +Inf */
+            return Double.NEGATIVE_INFINITY;
+        }
+
+        if (p >= 10) {
+            /* p and q are big. */
+            corr = lgammacor(p) + lgammacor(q) - lgammacor(p + q);
+            return Math.log(q) * -0.5 + M_LN_SQRT_2PI + corr + (p - 0.5) * Math.log(p / (p + q)) + q * Math.log1p(-p / (p + q));
+        } else if (q >= 10) {
+            /* p is small, but q is big. */
+            corr = lgammacor(q) - lgammacor(p + q);
+            return lgammafn(p) + corr + p - p * Math.log(p + q) + (q - 0.5) * Math.log1p(-p / (p + q));
+        } else {
+            /* p and q are small: p <= q < 10. */
+            /* R change for very small args */
+            if (p < 1e-306) {
+                return lgamma(p) + (lgamma(q) - lgamma(p + q));
+            } else {
+                return Math.log(gammafn(p) * (gammafn(q) / gammafn(p + q)));
+            }
+        }
+    }
+}
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 8f0f1a07f4c6afeaa617d46b65a59e9ff9911cc0..1fbefb2a995f10460e01aef039b2ad94135b163c 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
@@ -77,6 +77,8 @@ public final class MathConstants {
     // log(sqrt(pi/2)) == log(pi/2)/2
     public static final double M_LN_SQRT_PId2 = 0.225791352644727432363097614947;
 
+    public static final double DBL_EPSILON = Math.ulp(1.0);
+
     /**
      * Compute the log of a sum from logs of terms, i.e.,
      *
@@ -90,7 +92,9 @@ public final class MathConstants {
     }
 
     // R_forceint
-    public static long forceint(double x) {
-        return Math.round(x);
+    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/QHyper.java b/com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/stats/QHyper.java
new file mode 100644
index 0000000000000000000000000000000000000000..d3e23b0e73276ac48c384b17a182ec639278afcb
--- /dev/null
+++ b/com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/stats/QHyper.java
@@ -0,0 +1,98 @@
+/*
+ * 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 static com.oracle.truffle.r.library.stats.MathConstants.forceint;
+import static com.oracle.truffle.r.library.stats.StatsUtil.fmax2;
+import static com.oracle.truffle.r.library.stats.StatsUtil.fmin2;
+import static com.oracle.truffle.r.library.stats.StatsUtil.lfastchoose;
+
+import com.oracle.truffle.r.library.stats.DPQ.EarlyReturn;
+
+public final class QHyper {
+    public static double qhyper(double p, double nr, double nb, double n, 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.isFinite(p) || !Double.isFinite(nr) || !Double.isFinite(nb) || !Double.isFinite(n)) {
+            return StatsUtil.mlError();
+        }
+
+        nr = forceint(nr);
+        nb = forceint(nb);
+        capN = nr + nb;
+        n = forceint(n);
+        if (nr < 0 || nb < 0 || n < 0 || n > capN) {
+            return StatsUtil.mlError();
+        }
+
+        /*
+         * Goal: Find xr (= #{red balls in sample}) such that phyper(xr, NR,NB, n) >= p > phyper(xr
+         * - 1, NR,NB, n)
+         */
+
+        xstart = fmax2(0, n - nb);
+        xend = fmin2(n, nr);
+
+        try {
+            DPQ.qP01Boundaries(p, xstart, xend, lowerTail, logP);
+        } catch (EarlyReturn ex) {
+            return ex.result;
+        }
+
+        xr = xstart;
+        xb = n - xr; /* always ( = #{black balls in sample} ) */
+
+        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);
+        if (smallN) {
+            term = Math.exp(term);
+        }
+        nr -= xr;
+        nb -= xb;
+
+        if (!lowerTail || logP) {
+            p = DPQ.dtQIv(p, lowerTail, logP);
+        }
+        p *= 1 - 1000 * DBL_EPSILON; /* was 64, but failed on FreeBSD sometimes */
+        sum = smallN ? term : Math.exp(term);
+
+        while (sum < p && xr < xend) {
+            xr++;
+            nb++;
+            if (smallN) {
+                term *= (nr / xr) * (xb / nb);
+            } else {
+                term += Math.log((nr / xr) * (xb / nb));
+            }
+            sum += smallN ? term : Math.exp(term);
+            xb--;
+            nr--;
+        }
+        return xr;
+    }
+
+}
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 d7e72dd1f0745a5be4e65d8488bc54fdaee65656..9ba8e64a12ac14fa2575067e12d4dc4b878b8eec 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
@@ -18,22 +18,22 @@ import static com.oracle.truffle.r.library.stats.StatsUtil.fmax2;
 import static com.oracle.truffle.r.library.stats.StatsUtil.fmin2;
 
 import com.oracle.truffle.r.library.stats.RandGenerationFunctions.RandFunction2_Double;
-import com.oracle.truffle.r.runtime.rng.RandomNumberNode;
+import com.oracle.truffle.r.library.stats.RandGenerationFunctions.RandomNumberProvider;
 
 public final class RBeta implements RandFunction2_Double {
 
     private static final double expmax = (DBL_MAX_EXP * M_LN2); /* = log(DBL_MAX) */
 
     @Override
-    public double evaluate(int index, double aa, double bb, double random, RandomNumberNode randomNode) {
+    public double evaluate(double aa, double bb, RandomNumberProvider rand) {
         if (Double.isNaN(aa) || Double.isNaN(bb) || aa < 0. || bb < 0.) {
-            StatsUtil.mlError();
+            return StatsUtil.mlError();
         }
         if (!Double.isFinite(aa) && !Double.isFinite(bb)) { // a = b = Inf : all mass at 1/2
             return 0.5;
         }
         if (aa == 0. && bb == 0.) { // point mass 1/2 at each of {0,1} :
-            return (randomNode.executeSingleDouble() < 0.5) ? 0. : 1.;
+            return (rand.unifRand() < 0.5) ? 0. : 1.;
         }
         // now, at least one of a, b is finite and positive
         if (!Double.isFinite(aa) || bb == 0.) {
@@ -54,14 +54,15 @@ public final class RBeta implements RandFunction2_Double {
         double w = 0;
         double y;
         double z;
-        double olda = -1.0;
-        double oldb = -1.0;
 
+        // 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);
@@ -84,8 +85,8 @@ public final class RBeta implements RandFunction2_Double {
             }
             /* FIXME: "do { } while()", but not trivially because of "continue"s: */
             for (;;) {
-                u1 = randomNode.executeSingleDouble();
-                u2 = randomNode.executeSingleDouble();
+                u1 = rand.unifRand();
+                u2 = rand.unifRand();
                 if (u1 < 0.5) {
                     y = u1 * u2;
                     z = u1 * y;
@@ -120,8 +121,8 @@ public final class RBeta implements RandFunction2_Double {
                 gamma = a + 1.0 / beta;
             }
             do {
-                u1 = randomNode.executeSingleDouble();
-                u2 = randomNode.executeSingleDouble();
+                u1 = rand.unifRand();
+                u2 = rand.unifRand();
 
                 v = beta * Math.log(u1 / (1.0 - u1));
                 w = wFromU1Bet(a, v, w);
diff --git a/com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/stats/RCauchy.java b/com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/stats/RCauchy.java
index 4ec84f33dd4c9433818f7ebe0919bea71468ffe8..accf46e7c246e8914ab9075568984edbe7194507 100644
--- a/com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/stats/RCauchy.java
+++ b/com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/stats/RCauchy.java
@@ -14,18 +14,18 @@ package com.oracle.truffle.r.library.stats;
 import static com.oracle.truffle.r.library.stats.MathConstants.M_PI;
 
 import com.oracle.truffle.r.library.stats.RandGenerationFunctions.RandFunction2_Double;
-import com.oracle.truffle.r.runtime.rng.RandomNumberNode;
+import com.oracle.truffle.r.library.stats.RandGenerationFunctions.RandomNumberProvider;
 
 public final class RCauchy implements RandFunction2_Double {
     @Override
-    public double evaluate(int index, double location, double scale, double random, RandomNumberNode randomNode) {
+    public double evaluate(double location, double scale, RandomNumberProvider rand) {
         if (Double.isNaN(location) || !Double.isFinite(scale) || scale < 0) {
             return StatsUtil.mlError();
         }
         if (scale == 0. || !Double.isFinite(location)) {
             return location;
         } else {
-            return location + scale * Math.tan(M_PI * randomNode.executeSingleDouble());
+            return location + scale * Math.tan(M_PI * rand.unifRand());
         }
     }
 }
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
new file mode 100644
index 0000000000000000000000000000000000000000..3b4c21ac102e287b7f0c21c0fdd01a6dd7eff473
--- /dev/null
+++ b/com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/stats/RChisq.java
@@ -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) 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 StatsUtil.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/RExp.java b/com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/stats/RExp.java
new file mode 100644
index 0000000000000000000000000000000000000000..078f113dc20a407979ce7f75e2eb634ac663ea82
--- /dev/null
+++ b/com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/stats/RExp.java
@@ -0,0 +1,25 @@
+/*
+ * 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 RExp implements RandFunction1_Double {
+    @Override
+    public double evaluate(double scale, RandomNumberProvider rand) {
+        if (!Double.isFinite(scale) || scale <= 0.0) {
+            return scale == 0. ? 0. : StatsUtil.mlError();
+        }
+        return scale * rand.expRand();
+    }
+}
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
new file mode 100644
index 0000000000000000000000000000000000000000..0e8581b5035469b7af5bc26d512b224447bf5dfd
--- /dev/null
+++ b/com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/stats/RGamma.java
@@ -0,0 +1,207 @@
+/*
+ * 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 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 {
+    private static final double sqrt32 = 5.656854;
+    private static final double exp_m1 = 0.36787944117144232159; /* exp(-1) = 1/e */
+
+    /*
+     * Coefficients q[k] - for q0 = sum(q[k]*a^(-k)) Coefficients a[k] - for q =
+     * q0+(t*t/2)*sum(a[k]*v^k) Coefficients e[k] - for exp(q)-1 = sum(e[k]*q^k)
+     */
+    private static final double q1 = 0.04166669;
+    private static final double q2 = 0.02083148;
+    private static final double q3 = 0.00801191;
+    private static final double q4 = 0.00144121;
+    private static final double q5 = -7.388e-5;
+    private static final double q6 = 2.4511e-4;
+    private static final double q7 = 2.424e-4;
+
+    private static final double a1 = 0.3333333;
+    private static final double a2 = -0.250003;
+    private static final double a3 = 0.2000062;
+    private static final double a4 = -0.1662921;
+    private static final double a5 = 0.1423657;
+    private static final double a6 = -0.1367177;
+    private static final double a7 = 0.1233795;
+
+    @Override
+    public double evaluate(double a, double scale, RandomNumberProvider rand) {
+
+        // TODO: state variables
+        double aa = 0.;
+        double aaa = 0.;
+        double s = 0;
+        double s2 = 0;
+        double d = 0; /* no. 1 (step 1) */
+        double q0 = 0;
+        double b = 0;
+        double si = 0;
+        double c = 0; /* no. 2 (step 4) */
+
+        double e;
+        double p;
+        double q;
+        double r;
+        double t;
+        double u;
+        double v;
+        double w;
+        double x;
+        double retVal;
+
+        if (Double.isNaN(a) || Double.isNaN(scale)) {
+            return StatsUtil.mlError();
+        }
+        if (a <= 0.0 || scale <= 0.0) {
+            if (scale == 0. || a == 0.) {
+                return 0.;
+            }
+            return StatsUtil.mlError();
+        }
+        if (!Double.isFinite(a) || !Double.isFinite(scale)) {
+            return Double.POSITIVE_INFINITY;
+        }
+
+        if (a < 1.) { /* GS algorithm for parameters a < 1 */
+            e = 1.0 + exp_m1 * a;
+            while (true) {
+                p = e * rand.unifRand();
+                if (p >= 1.0) {
+                    x = -Math.log((e - p) / a);
+                    if (rand.expRand() >= (1.0 - a) * Math.log(x)) {
+                        break;
+                    }
+                } else {
+                    x = Math.exp(Math.log(p) / a);
+                    if (rand.expRand() >= x) {
+                        break;
+                    }
+                }
+            }
+            return scale * x;
+        }
+
+        /* --- a >= 1 : GD algorithm --- */
+
+        /* Step 1: Recalculations of s2, s, d if a has changed */
+        if (a != aa) {
+            aa = a;
+            s2 = a - 0.5;
+            s = Math.sqrt(s2);
+            d = sqrt32 - s * 12.0;
+        }
+        /*
+         * Step 2: t = standard normal deviate, x = (s,1/2) -normal deviate.
+         */
+
+        /* immediate acceptance (i) */
+        t = rand.normRand();
+        x = s + 0.5 * t;
+        retVal = x * x;
+        if (t >= 0.0) {
+            return scale * retVal;
+        }
+
+        /* Step 3: u = 0,1 - uniform sample. squeeze acceptance (s) */
+        u = rand.unifRand();
+        if (d * u <= Math.pow(t, 3)) {
+            return scale * retVal;
+        }
+
+        /* Step 4: recalculations of q0, b, si, c if necessary */
+
+        if (a != aaa) {
+            aaa = a;
+            r = 1.0 / a;
+            q0 = ((((((q7 * r + q6) * r + q5) * r + q4) * r + q3) * r + q2) * r + q1) * r;
+
+            /* Approximation depending on size of parameter a */
+            /* The constants in the expressions for b, si and c */
+            /* were established by numerical experiments */
+
+            if (a <= 3.686) {
+                b = 0.463 + s + 0.178 * s2;
+                si = 1.235;
+                c = 0.195 / s - 0.079 + 0.16 * s;
+            } else if (a <= 13.022) {
+                b = 1.654 + 0.0076 * s2;
+                si = 1.68 / s + 0.275;
+                c = 0.062 / s + 0.024;
+            } else {
+                b = 1.77;
+                si = 0.75;
+                c = 0.1515 / s;
+            }
+        }
+        /* Step 5: no quotient test if x not positive */
+
+        if (x > 0.0) {
+            /* Step 6: calculation of v and quotient q */
+            v = t / (s + s);
+            if (fabs(v) <= 0.25) {
+                q = q0 + 0.5 * t * t * ((((((a7 * v + a6) * v + a5) * v + a4) * v + a3) * v + a2) * v + a1) * v;
+            } else {
+                q = q0 - s * t + 0.25 * t * t + (s2 + s2) * Math.log(1.0 + v);
+            }
+
+            /* Step 7: quotient acceptance (q) */
+            if (Math.log(1.0 - u) <= q) {
+                return scale * retVal;
+            }
+        }
+
+        while (true) {
+            /*
+             * Step 8: e = standard exponential deviate u = 0,1 -uniform deviate t = (b,si)-double
+             * exponential (laplace) sample
+             */
+            e = rand.expRand();
+            u = rand.unifRand();
+            u = u + u - 1.0;
+            if (u < 0.0) {
+                t = b - si * e;
+            } else {
+                t = b + si * e;
+            }
+            /* Step 9: rejection if t < tau(1) = -0.71874483771719 */
+            if (t >= -0.71874483771719) {
+                /* Step 10: calculation of v and quotient q */
+                v = t / (s + s);
+                if (fabs(v) <= 0.25) {
+                    q = q0 + 0.5 * t * t *
+                                    ((((((a7 * v + a6) * v + a5) * v + a4) * v + a3) * v + a2) * v + a1) * v;
+                } else {
+                    q = q0 - s * t + 0.25 * t * t + (s2 + s2) * Math.log(1.0 + v);
+                }
+                /* Step 11: hat acceptance (h) */
+                /* (if q not positive go to step 8) */
+                if (q > 0.0) {
+                    w = StatsUtil.expm1(q);
+                    /* ^^^^^ original code had approximation with rel.err < 2e-7 */
+                    /* if t is rejected sample again at step 8 */
+                    if (c * fabs(u) <= w * Math.exp(e - 0.5 * t * t)) {
+                        break;
+                    }
+                }
+            }
+        } /* repeat .. until `t' is accepted */
+        x = s + 0.5 * t;
+        return scale * x * x;
+    }
+}
diff --git a/com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/stats/RGeom.java b/com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/stats/RGeom.java
new file mode 100644
index 0000000000000000000000000000000000000000..555d703a529b0e2021bf70e6ac116b93cdcd9467
--- /dev/null
+++ b/com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/stats/RGeom.java
@@ -0,0 +1,25 @@
+/*
+ * 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 RGeom implements RandFunction1_Double {
+    @Override
+    public double evaluate(double p, RandomNumberProvider rand) {
+        if (!Double.isFinite(p) || p <= 0 || p > 1) {
+            return StatsUtil.mlError();
+        }
+        return RPois.rpois(rand.expRand() * ((1 - p) / p), rand);
+    }
+}
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
new file mode 100644
index 0000000000000000000000000000000000000000..32d9c6afee1cdf69754660e0d751057aefd13389
--- /dev/null
+++ b/com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/stats/RHyper.java
@@ -0,0 +1,364 @@
+/*
+ * 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--2009, The R Core Team
+ * Copyright (c) 2003--2009, The R Foundation
+ * Copyright (c) 2016, 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.M_LN_SQRT_2PI;
+import static com.oracle.truffle.r.library.stats.MathConstants.forceint;
+
+import com.oracle.truffle.api.CompilerDirectives.TruffleBoundary;
+import com.oracle.truffle.r.library.stats.RandGenerationFunctions.RandFunction3_Double;
+import com.oracle.truffle.r.library.stats.RandGenerationFunctions.RandomNumberProvider;
+import com.oracle.truffle.r.runtime.RError;
+import com.oracle.truffle.r.runtime.RError.Message;
+
+public final class RHyper implements RandFunction3_Double {
+    private static final double[] al = {
+                    0.0, /* ln(0!)=ln(1) */
+                    0.0, /* ln(1!)=ln(1) */
+                    0.69314718055994530941723212145817, /* ln(2) */
+                    1.79175946922805500081247735838070, /* ln(6) */
+                    3.17805383034794561964694160129705, /* ln(24) */
+                    4.78749174278204599424770093452324,
+                    6.57925121201010099506017829290394,
+                    8.52516136106541430016553103634712
+                    /*
+                     * 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)
+                     */
+    };
+
+    // afc(i) := ln( i! ) [Math.logarithm of the factorial i]
+    private static double afc(int i) {
+        // If (i > 7), use Stirling's approximation, otherwise use table lookup.
+        if (i < 0) {
+            RError.warning(RError.SHOW_CALLER, Message.GENERIC, String.format("RHyper.java: afc(i), i=%d < 0 -- SHOULD NOT HAPPEN!\n", i));
+            return -1;
+        }
+        if (i <= 7) {
+            return al[i];
+        }
+        // else i >= 8 :
+        double di = i;
+        double i2 = di * di;
+        return (di + 0.5) * Math.log(di) - di + M_LN_SQRT_2PI +
+                        (0.0833333333333333 - 0.00277777777777778 / i2) / di;
+    }
+
+    /* These should become 'thread_local globals' : */
+    private static int ks = -1;
+    private static int n1s = -1;
+    private static int n2s = -1;
+    private static int m;
+    private static int minjx;
+    private static int maxjx;
+    private static int k;
+    private static int n1;
+    private static int n2; // <- not allowing larger integer par
+    private static double tn;
+
+    // II :
+    private static double w;
+    // III:
+    // Checkstyle: stop
+    private static double a, d, s, xl, xr, kl, kr, lamdl, lamdr, p1, p2, p3;
+    // // Checkstyle: resume
+
+    private static final double scale = 1e25; // scaling factor against (early) underflow
+    private static final double con = 57.5646273248511421;
+
+    private static final double deltal = 0.0078;
+    private static final double deltau = 0.0034;
+
+    private final Rbinom rbinom = new Rbinom();
+
+    // 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) {
+        /* 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 StatsUtil.mlError();
+        }
+
+        nn1in = forceint(nn1in);
+        nn2in = forceint(nn2in);
+        kkin = forceint(kkin);
+
+        if (nn1in < 0 || nn2in < 0 || kkin < 0 || kkin > nn1in + nn2in) {
+            return StatsUtil.mlError();
+        }
+        if (nn1in >= Integer.MAX_VALUE || nn2in >= Integer.MAX_VALUE || kkin >= 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);
+            }
+            // 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);
+        }
+        nn1 = (int) nn1in;
+        nn2 = (int) nn2in;
+        kk = (int) kkin;
+
+        /* if new parameter values, initialize */
+        if (nn1 != n1s || nn2 != n2s) {
+            setup1 = true;
+            setup2 = true;
+        } else if (kk != ks) {
+            setup1 = false;
+            setup2 = true;
+        } else {
+            setup1 = false;
+            setup2 = false;
+        }
+        if (setup1) {
+            n1s = nn1;
+            n2s = nn2;
+            tn = nn1 + nn2;
+            if (nn1 <= nn2) {
+                n1 = nn1;
+                n2 = nn2;
+            } else {
+                n1 = nn2;
+                n2 = nn1;
+            }
+        }
+        if (setup2) {
+            ks = kk;
+            if (kk + kk >= tn) {
+                k = (int) (tn - kk);
+            } else {
+                k = kk;
+            }
+        }
+        if (setup1 || setup2) {
+            m = (int) ((k + 1.) * (n1 + 1.) / (tn + 2.));
+            minjx = Math.max(0, k - n2);
+            maxjx = Math.min(n1, k);
+        }
+        /* generate random variate --- Three basic cases */
+
+        if (minjx == maxjx) { /*
+                               * I: degenerate distribution ----------------
+                               */
+            ix = maxjx;
+
+        } else if (m - minjx < 10) { // II: (Scaled) algorithm HIN
+                                     // (inverse transformation)
+                                     // ----
+            // 25*Math.log(10) = Math.log(scale) { <==> Math.exp(con) == scale }
+            if (setup1 || setup2) {
+                double lw; // Math.log(w); w = Math.exp(lw) * scale = Math.exp(lw +
+                           // Math.log(scale)) = Math.exp(lw + con)
+                if (k < n2) {
+                    lw = afc(n2) + afc(n1 + n2 - k) - afc(n2 - k) - afc(n1 + n2);
+                } else {
+                    lw = afc(n1) + afc(k) - afc(k - n2) - afc(n1 + n2);
+                }
+                w = Math.exp(lw + con);
+            }
+            L10: while (true) {
+                double p = w;
+                ix = minjx;
+                double u = rand.unifRand() * scale;
+                while (u > p) {
+                    u -= p;
+                    p *= ((double) n1 - ix) * (k - ix);
+                    ix++;
+                    p = p / ix / (n2 - k + ix);
+                    if (ix > maxjx) {
+                        continue L10;
+                    }
+                    // FIXME if(p == 0.) we also "have lost" => goto L10
+                }
+                break L10;
+            }
+        } else { /* III : H2PE Algorithm --------------------------------------- */
+
+            double u;
+            double v;
+
+            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;
+                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)));
+                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;
+                p2 = p1 + kl / lamdl;
+                p3 = p2 + kr / lamdr;
+            }
+            int nUv = 0;
+            L30: while (true) {
+
+                u = rand.unifRand() * p3;
+                v = rand.unifRand();
+                nUv++;
+                if (nUv >= 10000) {
+                    RError.warning(RError.SHOW_CALLER, Message.GENERIC, String.format("rhyper() branch III: giving up after %d rejections", nUv));
+                    return StatsUtil.mlError();
+                }
+
+                if (u < p1) { /* rectangular region */
+                    ix = (int) (xl + u);
+                } else if (u <= p2) { /* left tail */
+                    ix = (int) (xl + Math.log(v) / lamdl);
+                    if (ix < minjx) {
+                        continue L30;
+                    }
+                    v = v * (u - p1) * lamdl;
+                } else { /* right tail */
+                    ix = (int) (xr - Math.log(v) / lamdr);
+                    if (ix > maxjx) {
+                        continue L30;
+                    }
+                    v = v * (u - p2) * lamdr;
+                }
+
+                /* acceptance/rejection test */
+                boolean reject = true;
+
+                if (m < 100 || ix <= 50) {
+                    /* Math.explicit evaluation */
+                    /*
+                     * The original algorithm (and TOMS 668) have f = f * i * (n2 - k + i) / (n1 -
+                     * i) / (k - i); in the (m > ix) case, but the definition of the recurrence
+                     * relation on p134 shows that the +1 is needed.
+                     */
+                    int i;
+                    double f = 1.0;
+                    if (m < ix) {
+                        for (i = m + 1; i <= ix; i++) {
+                            f = f * (n1 - i + 1) * (k - i + 1) / (n2 - k + i) / i;
+                        }
+                    } else if (m > ix) {
+                        for (i = ix + 1; i <= m; i++) {
+                            f = f * i * (n2 - k + i) / (n1 - i + 1) / (k - i + 1);
+                        }
+                    }
+                    if (v <= f) {
+                        reject = false;
+                    }
+                } else {
+                    // Checkstyle: stop
+                    double e, g, r, t, y;
+                    double de, dg, dr, ds, dt, gl, gu, nk, nm, ub;
+                    double xk, xm, xn, y1, ym, yn, yk, alv;
+                    // Checkstyle: resume
+
+                    /* squeeze using upper and lower bounds */
+                    y = ix;
+                    y1 = y + 1.0;
+                    ym = y - m;
+                    yn = n1 - y + 1.0;
+                    yk = k - y + 1.0;
+                    nk = n2 - k + y1;
+                    r = -ym / y1;
+                    s = ym / yn;
+                    t = ym / yk;
+                    e = -ym / nk;
+                    g = yn * yk / (y1 * nk) - 1.0;
+                    dg = 1.0;
+                    if (g < 0.0) {
+                        dg = 1.0 + g;
+                    }
+                    gu = g * (1.0 + g * (-0.5 + g / 3.0));
+                    gl = gu - .25 * (g * g * g * g) / dg;
+                    xm = m + 0.5;
+                    xn = n1 - m + 0.5;
+                    xk = k - m + 0.5;
+                    nm = n2 - k + xm;
+                    ub = y * gu - m * gl + deltau + xm * r * (1. + r * (-0.5 + r / 3.0)) + xn * s * (1. + s * (-0.5 + s / 3.0)) + xk * t * (1. + t * (-0.5 + t / 3.0)) +
+                                    nm * e * (1. + e * (-0.5 + e / 3.0));
+                    /* test against upper bound */
+                    alv = Math.log(v);
+                    if (alv > ub) {
+                        reject = true;
+                    } else {
+                        /* test against lower bound */
+                        dr = xm * (r * r * r * r);
+                        if (r < 0.0) {
+                            dr /= (1.0 + r);
+                        }
+                        ds = xn * (s * s * s * s);
+                        if (s < 0.0) {
+                            ds /= (1.0 + s);
+                        }
+                        dt = xk * (t * t * t * t);
+                        if (t < 0.0) {
+                            dt /= (1.0 + t);
+                        }
+                        de = nm * (e * e * e * e);
+                        if (e < 0.0) {
+                            de /= (1.0 + e);
+                        }
+                        if (alv < ub - 0.25 * (dr + ds + dt + de) + (y + m) * (gl - gu) - deltal) {
+                            reject = false;
+                        } else {
+                            /*
+                             * * 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;
+                            }
+                        }
+                    }
+                } // else
+                if (!reject) {
+                    break L30; // e.g. if (reject) goto L30;
+                }
+            }
+        }
+
+        /* return appropriate variate */
+        double ix1 = ix;
+        if ((double) kk + (double) kk >= tn) {
+            if ((double) nn1 > (double) nn2) {
+                ix1 = (double) kk - (double) nn2 + ix1;
+            } else {
+                ix1 = (double) nn1 - ix1;
+            }
+        } else {
+            if ((double) nn1 > (double) nn2) {
+                ix1 = (double) 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
new file mode 100644
index 0000000000000000000000000000000000000000..007b812f841e234635bf6880d12728f879add390
--- /dev/null
+++ b/com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/stats/RLogis.java
@@ -0,0 +1,31 @@
+/*
+ * 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 StatsUtil.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/RMultinom.java b/com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/stats/RMultinom.java
new file mode 100644
index 0000000000000000000000000000000000000000..7a49a79e36cf75d48bb04762daeac1bb7e791042
--- /dev/null
+++ b/com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/stats/RMultinom.java
@@ -0,0 +1,185 @@
+/*
+ * 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) 1997-2012, The R Core Team
+ * Copyright (c) 2003-2008, 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.nodes.builtin.CastBuilder.Predef.notIntNA;
+import static com.oracle.truffle.r.runtime.RError.Message.NA_IN_PROB_VECTOR;
+import static com.oracle.truffle.r.runtime.RError.Message.NEGATIVE_PROBABILITY;
+import static com.oracle.truffle.r.runtime.RError.Message.NO_POSITIVE_PROBABILITIES;
+import static com.oracle.truffle.r.runtime.RError.SHOW_CALLER;
+
+import java.math.BigDecimal;
+import java.math.RoundingMode;
+
+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.ConditionProfile;
+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.runtime.RError;
+import com.oracle.truffle.r.runtime.RError.Message;
+import com.oracle.truffle.r.runtime.RRuntime;
+import com.oracle.truffle.r.runtime.data.RDataFactory;
+import com.oracle.truffle.r.runtime.data.RIntVector;
+import com.oracle.truffle.r.runtime.data.RNull;
+import com.oracle.truffle.r.runtime.data.model.RAbstractDoubleVector;
+import com.oracle.truffle.r.runtime.rng.RRNG;
+
+public abstract class RMultinom extends RExternalBuiltinNode.Arg3 {
+
+    private final Rbinom rbinom = new Rbinom();
+
+    @Override
+    protected void createCasts(CastBuilder casts) {
+        casts.arg(0).asIntegerVector().findFirst().mustBe(notIntNA(), SHOW_CALLER, Message.INVALID_FIRST_ARGUMENT_NAME, "n");
+        casts.arg(1).asIntegerVector().findFirst().mustBe(notIntNA(), SHOW_CALLER, Message.INVALID_SECOND_ARGUMENT_NAME, "size");
+        casts.arg(2).asDoubleVector();
+    }
+
+    @Specialization
+    protected RIntVector doMultinom(int n, int size, RAbstractDoubleVector probsVec,
+                    @Cached("create()") ReuseNonSharedNode reuseNonSharedNode,
+                    @Cached("createClassProfile()") ValueProfile randGeneratorClassProfile,
+                    @Cached("createBinaryProfile()") ConditionProfile hasAttributesProfile,
+                    @Cached("create()") UpdateSharedAttributeNode updateSharedAttributeNode,
+                    @Cached("createNames()") GetFixedAttributeNode getNamesNode,
+                    @Cached("createDimNames()") SetFixedAttributeNode setDimNamesNode) {
+        RAbstractDoubleVector nonSharedProbs = (RAbstractDoubleVector) reuseNonSharedNode.execute(probsVec);
+        double[] probs = nonSharedProbs.materialize().getDataWithoutCopying();
+        fixupProb(probs);
+
+        RRNG.getRNGState();
+        RandomNumberProvider rand = new RandomNumberProvider(randGeneratorClassProfile.profile(RRNG.currentGenerator()), RRNG.currentNormKind());
+        int k = probs.length;
+        int[] result = new int[k * n];
+        boolean isComplete = true;
+        for (int i = 0, ik = 0; i < n; i++, ik += k) {
+            isComplete &= rmultinom(size, probs, k, result, ik, rand);
+        }
+        RRNG.putRNGState();
+
+        // take names from probVec (if any) as row names in the result
+        RIntVector resultVec = RDataFactory.createIntVector(result, isComplete, new int[]{k, n});
+        if (hasAttributesProfile.profile(probsVec.getAttributes() != null)) {
+            Object probsNames = getNamesNode.execute(probsVec.getAttributes());
+            updateSharedAttributeNode.execute(probsVec, probsNames);
+            Object[] dimnamesData = new Object[]{probsNames, RNull.instance};
+            setDimNamesNode.execute(resultVec.getAttributes(), RDataFactory.createList(dimnamesData));
+        }
+        return resultVec;
+    }
+
+    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])) {
+                throw RError.error(SHOW_CALLER, NA_IN_PROB_VECTOR);
+            }
+            if (p[i] < 0.0) {
+                throw RError.error(SHOW_CALLER, NEGATIVE_PROBABILITY);
+            }
+            if (p[i] > 0.0) {
+                npos++;
+                sum += p[i];
+            }
+        }
+        if (npos == 0) {
+            throw RError.error(SHOW_CALLER, NO_POSITIVE_PROBABILITIES);
+        }
+        for (int i = 0; i < p.length; i++) {
+            p[i] /= sum;
+        }
+    }
+
+    /**
+     * Returns true if no element of the vector rN got assigned value NA, i.e. is stayed complete if
+     * it was before. GnuR doc: `Return' vector rN[1:K] {K := length(prob)} where rN[j] ~ Bin(n,
+     * 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;
+        BigDecimal pTot = BigDecimal.ZERO;
+        /*
+         * This calculation is sensitive to exact values, so we try to ensure that the calculations
+         * are as accurate as possible so different platforms are more likely to give the same
+         * result.
+         */
+
+        if (RRuntime.isNA(maxK) || maxK < 1 || RRuntime.isNA(n) || n < 0) {
+            if (rN.length > rnStartIdx) {
+                rN[rnStartIdx] = RRuntime.INT_NA;
+            }
+            return false;
+        }
+
+        /*
+         * 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];
+            if (!Double.isFinite(pp) || pp < 0. || pp > 1.) {
+                rN[rnStartIdx + k] = RRuntime.INT_NA;
+                return false;
+            }
+            pTot = pTot.add(new BigDecimal(pp));
+            rN[rnStartIdx + k] = 0;
+        }
+
+        BigDecimal probSum = pTot.subtract(BigDecimal.ONE).abs();
+        if (probSum.compareTo(new BigDecimal(1e-7)) == 1) {
+            throw RError.error(SHOW_CALLER, Message.GENERIC, String.format("rbinom: probability sum should be 1, but is %s", pTot.toPlainString()));
+        }
+        if (n == 0) {
+            return true;
+        }
+        if (maxK == 1 && pTot.compareTo(BigDecimal.ZERO) == 0) {
+            return true; /* trivial border case: do as rbinom */
+        }
+
+        /* Generate the first K-1 obs. via binomials */
+        for (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();
+                // System.out.printf("[%d] %.17f\n", k + 1, pp);
+                rN[rnStartIdx + k] = ((pp < 1.) ? (int) rbinom.evaluate((double) n, pp, rand) :
+                /* >= 1; > 1 happens because of rounding */
+                                n);
+                n -= rN[rnStartIdx + k];
+            } else {
+                rN[rnStartIdx + k] = 0;
+            }
+            if (n <= 0) {
+                /* we have all */
+                return true;
+            }
+            /* i.e. = sum(prob[(k+1):K]) */
+            pTot = pTot.subtract(probK);
+        }
+
+        rN[rnStartIdx + maxK - 1] = n;
+        return true;
+    }
+
+}
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
new file mode 100644
index 0000000000000000000000000000000000000000..bac788a88f092635d86a66edb0f39d218c08f813
--- /dev/null
+++ b/com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/stats/RNbinomMu.java
@@ -0,0 +1,30 @@
+/*
+ * 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 RNbinomMu implements 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 StatsUtil.mlError();
+        }
+        if (!Double.isFinite(size)) {
+            size = Double.MAX_VALUE / 2.;
+        }
+        return (mu == 0) ? 0 : RPois.rpois(rgamma.evaluate(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
new file mode 100644
index 0000000000000000000000000000000000000000..da55025e1ad1d072053cd34ce4dab98b98260a8e
--- /dev/null
+++ b/com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/stats/RNchisq.java
@@ -0,0 +1,41 @@
+/*
+ * 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-2015, The R Core Team
+ * Copyright (c) 2015, The R Foundation
+ * Copyright (c) 2016, Oracle and/or its affiliates
+ *
+ * All rights reserved.
+ */
+
+// TODO: fix copyright
+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 {
+    private final RGamma rgamma = new RGamma();
+
+    @Override
+    public double evaluate(double df, double lambda, RandomNumberProvider rand) {
+        if (!Double.isFinite(df) || !Double.isFinite(lambda) || df < 0. || lambda < 0.) {
+            return StatsUtil.mlError();
+        }
+
+        if (lambda == 0.) {
+            return (df == 0.) ? 0. : rgamma.evaluate(df / 2., 2., rand);
+        } else {
+            double r = RPois.rpois(lambda / 2., rand);
+            if (r > 0.) {
+                r = RChisq.rchisq(2. * r, rand);
+            }
+            if (df > 0.) {
+                r += rgamma.evaluate(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
new file mode 100644
index 0000000000000000000000000000000000000000..ffcc999eace1ce6645b72423f3a7ee81f7cbb191
--- /dev/null
+++ b/com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/stats/RPois.java
@@ -0,0 +1,281 @@
+/*
+ * 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 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 {
+
+    private static final double a0 = -0.5;
+    private static final double a1 = 0.3333333;
+    private static final double a2 = -0.2500068;
+    private static final double a3 = 0.2000118;
+    private static final double a4 = -0.1661269;
+    private static final double a5 = 0.1421878;
+    private static final double a6 = -0.1384794;
+    private static final double a7 = 0.1250060;
+
+    private static final double one_7 = 0.1428571428571428571;
+    private static final double one_12 = 0.0833333333333333333;
+    private static final double one_24 = 0.0416666666666666667;
+
+    /* Factorial Table (0:9)! */
+    private static final double[] fact = new double[]{
+                    1., 1., 2., 6., 24., 120., 720., 5040., 40320., 362880.
+    };
+
+    /* 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. */
+
+    public static double rpois(double mu, RandomNumberProvider rand) {
+        /* Local Vars [initialize some for -Wall]: */
+        double del;
+        double difmuk = 0.;
+        double e = 0.;
+        double fk = 0.;
+        double fx;
+        double fy;
+        double g;
+        double px;
+        double py;
+        double t = 0;
+        double u = 0.;
+        double v;
+        double x;
+        double pois = -1.;
+        int k;
+        int kflag = 0;
+        boolean bigMu;
+        boolean newBigMu = false;
+
+        if (!Double.isFinite(mu) || mu < 0) {
+            return StatsUtil.mlError();
+        }
+
+        if (mu <= 0.) {
+            return 0.;
+        }
+
+        bigMu = mu >= 10.;
+        if (bigMu) {
+            newBigMu = false;
+        }
+
+        if (!(bigMu && mu == muprev)) { /* maybe compute new persistent par.s */
+
+            if (bigMu) {
+                newBigMu = true;
+                /*
+                 * Case A. (recalculation of s,d,l because mu has changed): The poisson
+                 * probabilities pk exceed the discrete normal probabilities fk whenever k >= m(mu).
+                 */
+                muprev = mu;
+                s = Math.sqrt(mu);
+                d = 6. * mu * mu;
+                bigL = Math.floor(mu - 1.1484);
+                /* = an upper bound to m(mu) for all mu >= 10. */
+            } else { /* Small mu ( < 10) -- not using normal approx. */
+
+                /* Case B. (start new table and calculate p0 if necessary) */
+
+                /* muprev = 0.;-* such that next time, mu != muprev .. */
+                if (mu != muprev) {
+                    muprev = mu;
+                    m = Math.max(1, (int) mu);
+                    l = 0; /* pp[] is already ok up to pp[l] */
+                    q = p0 = p = Math.exp(-mu);
+                }
+
+                while (true) {
+                    /* Step U. uniform sample for inversion method */
+                    u = rand.unifRand();
+                    if (u <= p0) {
+                        return 0.;
+                    }
+
+                    /*
+                     * Step T. table comparison until the end pp[l] of the pp-table of cumulative
+                     * poisson probabilities (0.458 > ~= pp[9](= 0.45792971447) for mu=10 )
+                     */
+                    if (l != 0) {
+                        for (k = (u <= 0.458) ? 1 : Math.min(l, m); k <= l; k++) {
+                            if (u <= pp[k]) {
+                                return (double) k;
+                            }
+                        }
+                        if (l == 35) { /* u > pp[35] */
+                            continue;
+                        }
+                    }
+                    /*
+                     * Step C. creation of new poisson probabilities p[l..] and their cumulatives q
+                     * =: pp[k]
+                     */
+                    l++;
+                    for (k = l; k <= 35; k++) {
+                        p *= mu / k;
+                        q += p;
+                        pp[k] = q;
+                        if (u <= q) {
+                            l = k;
+                            return (double) k;
+                        }
+                    }
+                    l = 35;
+                } /* end(repeat) */
+            } /* mu < 10 */
+
+        } /* end {initialize persistent vars} */
+
+        /* Only if mu >= 10 : ----------------------- */
+
+        /* Step N. normal sample */
+        g = mu + s * rand.normRand(); /* norm_rand() ~ N(0,1), standard normal */
+
+        if (g >= 0.) {
+            pois = Math.floor(g);
+            /* Step I. immediate acceptance if pois is large enough */
+            if (pois >= bigL) {
+                return pois;
+            }
+            /* Step S. squeeze acceptance */
+            fk = pois;
+            difmuk = mu - fk;
+            u = rand.unifRand(); /* ~ U(0,1) - sample */
+            if (d * u >= difmuk * difmuk * difmuk) {
+                return pois;
+            }
+        }
+
+        /*
+         * Step P. preparations for steps Q and H. (recalculations of parameters if necessary)
+         */
+
+        if (newBigMu || mu != muprev2) {
+            /*
+             * Careful! muprev2 is not always == muprev because one might have exited in step I or S
+             */
+            muprev2 = mu;
+            omega = M_1_SQRT_2PI / s;
+            /*
+             * The quantities b1, b2, c3, c2, c1, c0 are for the Hermite approximations to the
+             * discrete normal probabilities fk.
+             */
+
+            b1 = one_24 / mu;
+            b2 = 0.3 * b1 * b1;
+            c3 = one_7 * b1 * b2;
+            c2 = b2 - 15. * c3;
+            c1 = b1 - 6. * b2 + 45. * c3;
+            c0 = 1. - b1 + 3. * b2 - 15. * c3;
+            c = 0.1069 / mu; /* guarantees majorization by the 'hat'-function. */
+        }
+
+        boolean gotoStepF = false;
+        if (g >= 0.) {
+            /* 'Subroutine' F is called (kflag=0 for correct return) */
+            kflag = 0;
+            gotoStepF = true;
+            // goto Step_F;
+        }
+
+        while (true) {
+            if (!gotoStepF) {
+                /* Step E. Exponential Sample */
+                e = rand.expRand(); /* ~ Exp(1) (standard exponential) */
+
+                /*
+                 * sample t from the laplace 'hat' (if t <= -0.6744 then pk < fk for all mu >= 10.)
+                 */
+                u = 2 * rand.unifRand() - 1.;
+                t = 1.8 + StatsUtil.fsign(e, u);
+            }
+
+            if (t > -0.6744 || gotoStepF) {
+                if (!gotoStepF) {
+                    pois = Math.floor(mu + s * t);
+                    fk = pois;
+                    difmuk = mu - fk;
+
+                    /* 'subroutine' F is called (kflag=1 for correct return) */
+                    kflag = 1;
+                }
+
+                // Step_F: /* 'subroutine' F : calculation of px,py,fx,fy. */
+                gotoStepF = false;
+
+                if (pois < 10) { /* use factorials from table fact[] */
+                    px = -mu;
+                    py = Math.pow(mu, pois) / fact[(int) pois];
+                } else {
+                    /*
+                     * Case pois >= 10 uses polynomial approximation a0-a7 for accuracy when
+                     * advisable
+                     */
+                    del = one_12 / fk;
+                    del = del * (1. - 4.8 * del * del);
+                    v = difmuk / fk;
+                    if (TOMS708.fabs(v) <= 0.25) {
+                        px = fk * v * v * (((((((a7 * v + a6) * v + a5) * v + a4) *
+                                        v + a3) * v + a2) * v + a1) * v + a0) - del;
+                    } else { /* |v| > 1/4 */
+                        px = fk * Math.log(1. + v) - difmuk - del;
+                    }
+                    py = M_1_SQRT_2PI / Math.sqrt(fk);
+                }
+                x = (0.5 - difmuk) / s;
+                x *= x; /* x^2 */
+                fx = -0.5 * x;
+                fy = omega * (((c3 * x + c2) * x + c1) * x + c0);
+                if (kflag > 0) {
+                    /* Step H. Hat acceptance (E is repeated on rejection) */
+                    if (c * TOMS708.fabs(u) <= py * Math.exp(px + e) - fy * Math.exp(fx + e)) {
+                        break;
+                    }
+                } else {
+                    /* Step Q. Quotient acceptance (rare case) */
+                    if (fy - u * fy <= py * Math.exp(px - fx)) {
+                        break;
+                    }
+                }
+            } /* t > -.67.. */
+        }
+        return pois;
+    }
+
+    @Override
+    public double evaluate(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
new file mode 100644
index 0000000000000000000000000000000000000000..6e1fae2faf3211f4352d2dfae59e4a0a95c3c0d7
--- /dev/null
+++ b/com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/stats/RWeibull.java
@@ -0,0 +1,27 @@
+/*
+ * 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 RWeibull implements RandFunction2_Double {
+    @Override
+    public double evaluate(double shape, double scale, RandomNumberProvider rand) {
+        if (!Double.isFinite(shape) || !Double.isFinite(scale) || shape <= 0. || scale <= 0.) {
+            return scale == 0. ? 0. : StatsUtil.mlError();
+        }
+
+        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 b0d34cd6095b383d1ea66d9b4f1c103f64065a92..b3548e5ea37864b9ef8641ae6a6b5d13ac0b7e56 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
@@ -19,11 +19,13 @@ import static com.oracle.truffle.r.runtime.RError.SHOW_CALLER;
 
 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.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.nodes.builtin.CastBuilder;
 import com.oracle.truffle.r.nodes.builtin.RExternalBuiltinNode;
@@ -38,63 +40,60 @@ import com.oracle.truffle.r.runtime.data.model.RAbstractIntVector;
 import com.oracle.truffle.r.runtime.data.model.RAbstractVector;
 import com.oracle.truffle.r.runtime.nodes.RNode;
 import com.oracle.truffle.r.runtime.rng.RRNG;
-import com.oracle.truffle.r.runtime.rng.RandomNumberNode;
+import com.oracle.truffle.r.runtime.rng.RRNG.NormKind;
+import com.oracle.truffle.r.runtime.rng.RandomNumberGenerator;
 
 public final class RandGenerationFunctions {
-    private static final RDouble DUMMY_VECTOR = RDouble.valueOf(1);
+    @CompilationFinal private static final RDouble DUMMY_VECTOR = RDouble.valueOf(1);
 
     private RandGenerationFunctions() {
         // static class
     }
 
-    // inspired by the DEFRAND{X}_REAL and DEFRAND{X}_INT macros in GnuR
+    public static final class RandomNumberProvider {
+        private final RandomNumberGenerator generator;
+        private final NormKind normKind;
+
+        public RandomNumberProvider(RandomNumberGenerator generator, NormKind normKind) {
+            this.generator = generator;
+            this.normKind = normKind;
+        }
 
-    public interface RandFunction {
-        /**
-         * Allows to execute any initialization logic before the main loop that generates the
-         * resulting vector. This is place where the function should generate necessary random
-         * values if possible.
-         */
-        default void init(int resultLength, RandomNumberNode randNode) {
-            RRNG.getRNGState();
+        public double unifRand() {
+            return generator.genrandDouble();
         }
 
-        default void finish() {
-            RRNG.putRNGState();
+        public double normRand() {
+            return SNorm.normRand(generator, normKind);
+        }
+
+        public double expRand() {
+            return SExp.expRand(generator);
         }
     }
 
-    public interface RandFunction3_Int extends RandFunction {
-        int evaluate(int index, double a, double b, double c, RandomNumberNode randomNode);
+    // 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 interface RandFunction2_Int extends RandFunction3_Int {
+    public interface RandFunction2_Double extends RandFunction3_Double {
+        double evaluate(double a, double b, RandomNumberProvider rand);
+
         @Override
-        default int evaluate(int index, double a, double b, double c, RandomNumberNode randomNode) {
-            return evaluate(index, a, b, randomNode);
+        default double evaluate(double a, double b, double c, RandomNumberProvider rand) {
+            return evaluate(a, b, rand);
         }
-
-        int evaluate(int index, double a, double b, RandomNumberNode randomNode);
     }
 
-    public interface RandFunction2_Double extends RandFunction {
-        /**
-         * Opt-in possibility for random functions returning double: the infrastructure will
-         * preallocate array of random values and reuse it for storing the result. The random values
-         * will be passed to {@link #evaluate(int, double, double, double, RandomNumberNode)} as the
-         * 'random' argument. If this method returns {@code true} (default), the random numbers
-         * generation can be done in {@link #init(int, RandomNumberNode)} and {@link #finish()} or
-         * in {@link #evaluate(int, double, double, double, RandomNumberNode)}.
-         */
-        default boolean hasCustomRandomGeneration() {
-            return true;
-        }
-
-        /**
-         * Should generate the value that will be stored to the result vector under given index.
-         * Error is indicated by returning {@link StatsUtil#mlError()}.
-         */
-        double evaluate(int index, double a, double b, double random, RandomNumberNode randomNode);
+    public interface RandFunction1_Double extends RandFunction2_Double {
+        double evaluate(double a, RandomNumberProvider rand);
+
+        @Override
+        default double evaluate(double a, double b, RandomNumberProvider rand) {
+            return evaluate(a, rand);
+        }
     }
 
     static final class RandGenerationProfiles {
@@ -102,83 +101,92 @@ public final class RandGenerationFunctions {
         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_Int function, int lengthIn, RAbstractDoubleVector a, RAbstractDoubleVector b, RAbstractDoubleVector c,
-                    RandGenerationProfiles profiles, RandomNumberNode randNode) {
-        int length = profiles.resultVectorLengthProfile.profile(lengthIn);
+    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.NAN_PRODUCED);
+            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];
-        function.init(length, randNode);
+        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);
-            int value = function.evaluate(i, aValue, bValue, cValue, randNode);
-            if (Double.isNaN(value)) {
+            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;
             }
-            result[i] = value;
         }
-        function.finish();
+        RRNG.putRNGState();
         if (nans) {
-            RError.warning(SHOW_CALLER, RError.Message.NAN_PRODUCED);
+            RError.warning(SHOW_CALLER, RError.Message.NA_PRODUCED);
         }
         return RDataFactory.createIntVector(result, !nans);
     }
 
-    private static RAbstractDoubleVector evaluate2Double(Node node, RandFunction2_Double function, int lengthIn, RAbstractDoubleVector a, RAbstractDoubleVector b, RandGenerationProfiles profiles,
-                    RandomNumberNode randNode) {
-        int length = profiles.resultVectorLengthProfile.profile(lengthIn);
+    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();
-        if (aLength == 0 || bLength == 0) {
+        int cLength = c.getLength();
+        if (aLength == 0 || bLength == 0 || cLength == 0) {
             profiles.nanResult.enter();
-            RError.warning(SHOW_CALLER, RError.Message.NAN_PRODUCED);
+            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;
-        if (function.hasCustomRandomGeneration()) {
-            function.init(length, randNode);
-            result = new double[length];
-        } else {
-            RRNG.getRNGState();
-            result = randNode.executeDouble(length);
-            RRNG.putRNGState();
-        }
+        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 value = function.evaluate(i, aValue, bValue, result[i], randNode);
-            if (Double.isNaN(value)) {
+            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;
         }
-        if (function.hasCustomRandomGeneration()) {
-            function.finish();
-        }
+        RRNG.putRNGState();
         if (nans) {
             RError.warning(SHOW_CALLER, RError.Message.NA_PRODUCED);
         }
@@ -204,7 +212,7 @@ public final class RandGenerationFunctions {
                         @Cached("createNonPreserving()") CastIntegerNode castNode,
                         @Cached("create()") BranchProfile seenNA) {
             int result = ((RAbstractIntVector) castNode.execute(vector)).getDataAt(0);
-            if (RRuntime.isNA(result)) {
+            if (RRuntime.isNA(result) || result < 0) {
                 seenNA.enter();
                 throw RError.error(SHOW_CALLER, INVALID_UNNAMED_ARGUMENTS);
             }
@@ -222,10 +230,10 @@ public final class RandGenerationFunctions {
     }
 
     public abstract static class Function3_IntNode extends RExternalBuiltinNode.Arg4 {
-        private final RandFunction3_Int function;
+        private final RandFunction3_Double function;
         @Child private ConvertToLength convertToLength = ConvertToLengthNodeGen.create();
 
-        protected Function3_IntNode(RandFunction3_Int function) {
+        protected Function3_IntNode(RandFunction3_Double function) {
             this.function = function;
         }
 
@@ -239,17 +247,16 @@ public final class RandGenerationFunctions {
 
         @Specialization
         protected RAbstractIntVector evaluate(RAbstractVector length, RAbstractDoubleVector a, RAbstractDoubleVector b, RAbstractDoubleVector c,
-                        @Cached("create()") RandGenerationProfiles profiles,
-                        @Cached("create()") RandomNumberNode randNode) {
-            return evaluate3Int(this, function, convertToLength.execute(length), a, b, c, profiles, randNode);
+                        @Cached("create()") RandGenerationProfiles profiles) {
+            return evaluate3Int(this, function, convertToLength.execute(length), a, b, c, profiles);
         }
     }
 
     public abstract static class Function2_IntNode extends RExternalBuiltinNode.Arg3 {
-        private final RandFunction2_Int function;
+        private final RandFunction2_Double function;
         @Child private ConvertToLength convertToLength = ConvertToLengthNodeGen.create();
 
-        protected Function2_IntNode(RandFunction2_Int function) {
+        protected Function2_IntNode(RandFunction2_Double function) {
             this.function = function;
         }
 
@@ -262,9 +269,50 @@ public final class RandGenerationFunctions {
 
         @Specialization
         protected RAbstractIntVector evaluate(RAbstractVector length, RAbstractDoubleVector a, RAbstractDoubleVector b,
-                        @Cached("create()") RandGenerationProfiles profiles,
-                        @Cached("create()") RandomNumberNode randNode) {
-            return evaluate3Int(this, function, convertToLength.execute(length), a, b, DUMMY_VECTOR, profiles, randNode);
+                        @Cached("create()") RandGenerationProfiles profiles) {
+            return evaluate3Int(this, function, convertToLength.execute(length), a, b, DUMMY_VECTOR, profiles);
+        }
+    }
+
+    public abstract static class Function1_IntNode extends RExternalBuiltinNode.Arg2 {
+        private final RandFunction1_Double function;
+        @Child private ConvertToLength convertToLength = ConvertToLengthNodeGen.create();
+
+        protected Function1_IntNode(RandFunction1_Double function) {
+            this.function = function;
+        }
+
+        @Override
+        protected void createCasts(CastBuilder casts) {
+            ConvertToLength.addLengthCast(casts);
+            casts.arg(1).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);
+        }
+    }
+
+    public abstract static class Function1_DoubleNode extends RExternalBuiltinNode.Arg2 {
+        private final RandFunction1_Double function;
+        @Child private ConvertToLength convertToLength = ConvertToLengthNodeGen.create();
+
+        protected Function1_DoubleNode(RandFunction1_Double function) {
+            this.function = function;
+        }
+
+        @Override
+        protected void createCasts(CastBuilder casts) {
+            ConvertToLength.addLengthCast(casts);
+            casts.arg(1).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);
         }
     }
 
@@ -285,9 +333,8 @@ public final class RandGenerationFunctions {
 
         @Specialization
         protected RAbstractDoubleVector evaluate(RAbstractVector length, RAbstractDoubleVector a, RAbstractDoubleVector b,
-                        @Cached("create()") RandGenerationProfiles profiles,
-                        @Cached("create()") RandomNumberNode randNode) {
-            return evaluate2Double(this, function, convertToLength.execute(length), a, b, profiles, randNode);
+                        @Cached("create()") RandGenerationProfiles profiles) {
+            return evaluate3Double(this, function, convertToLength.execute(length), a, b, DUMMY_VECTOR, profiles);
         }
     }
 }
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 051c0822f9fb40f7f37f85bd232ecca4510e055d..db6545e1e193ce0332d1ef64f35802b55ab55aa2 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
@@ -12,22 +12,18 @@
  */
 package com.oracle.truffle.r.library.stats;
 
-import com.oracle.truffle.r.library.stats.RandGenerationFunctions.RandFunction2_Int;
+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.rng.RandomNumberNode;
 
 // transcribed from rbinom.c
 
-public final class Rbinom implements RandFunction2_Int {
+public final class Rbinom implements RandFunction2_Double {
 
     private final Qbinom qbinom = new Qbinom();
 
-    private static double unifRand(RandomNumberNode randNode) {
-        return randNode.executeDouble(1)[0];
-    }
-
     @Override
-    public int evaluate(int index, double nin, double pp, RandomNumberNode randomNode) {
+    public double evaluate(double nin, double pp, RandomNumberProvider rand) {
         double psave = -1.0;
         int nsave = -1;
 
@@ -54,7 +50,7 @@ public final class Rbinom implements RandFunction2_Int {
             /*
              * evade integer overflow, and r == INT_MAX gave only even values
              */
-            return (int) qbinom.evaluate(unifRand(randomNode), r, pp, /* lower_tail */false, /* log_p */false);
+            return (int) qbinom.evaluate(rand.unifRand(), r, pp, /* lower_tail */false, /* log_p */false);
         }
         /* else */
         int n = (int) r;
@@ -135,8 +131,8 @@ public final class Rbinom implements RandFunction2_Int {
 
                 /*-------------------------- np = n*p >= 30 : ------------------- */
                 while (true) {
-                    u = unifRand(randomNode) * p4;
-                    v = unifRand(randomNode);
+                    u = rand.unifRand() * p4;
+                    v = rand.unifRand();
                     /* triangular region */
                     if (u <= p1) {
                         ix = (int) (xm - p1 * v + u);
@@ -223,7 +219,7 @@ public final class Rbinom implements RandFunction2_Int {
             while (true) {
                 ix = 0;
                 f = qn;
-                u = unifRand(randomNode);
+                u = rand.unifRand();
                 while (true) {
                     if (u < f) {
                         // goto finis;
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
new file mode 100644
index 0000000000000000000000000000000000000000..5d9426797321df6200e4dbc4a00eb9c9e551cb87
--- /dev/null
+++ b/com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/stats/Rf.java
@@ -0,0 +1,30 @@
+/*
+ * 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 Rf implements RandFunction2_Double {
+    @Override
+    public double evaluate(double n1, double n2, RandomNumberProvider rand) {
+        if (Double.isNaN(n1) || Double.isNaN(n2) || n1 <= 0. || n2 <= 0.) {
+            return StatsUtil.mlError();
+        }
+
+        double v1;
+        double v2;
+        v1 = Double.isFinite(n1) ? (RChisq.rchisq(n1, rand) / n1) : 1;
+        v2 = Double.isFinite(n2) ? (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 b9872eff5c71a086460ac1ff5db0f35534747a82..24f2aed7d53b9d6f82635bec1bb53b441f4daa9b 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
@@ -12,28 +12,18 @@
 package com.oracle.truffle.r.library.stats;
 
 import com.oracle.truffle.r.library.stats.RandGenerationFunctions.RandFunction2_Double;
-import com.oracle.truffle.r.runtime.rng.RRNG;
-import com.oracle.truffle.r.runtime.rng.RandomNumberNode;
+import com.oracle.truffle.r.library.stats.RandGenerationFunctions.RandomNumberProvider;
 
 public final class Rnorm implements RandFunction2_Double {
-
-    private static final double BIG = 134217728;
-
-    @Override
-    public void init(int length, RandomNumberNode randNode) {
-        RRNG.getRNGState();
-    }
-
-    @Override
-    public void finish() {
-        RRNG.putRNGState();
-    }
-
     @Override
-    public double evaluate(int index, double mu, double sigma, double random, RandomNumberNode randomNode) {
-        // TODO: GnuR invokes norm_rand to get "rand"
-        double u1 = (int) (BIG * randomNode.executeSingleDouble()) + randomNode.executeSingleDouble();
-        double rand = Random2.qnorm5(u1 / BIG, 0.0, 1.0, true, false);
-        return rand * sigma + mu;
+    public double evaluate(double mu, double sigma, RandomNumberProvider rand) {
+        if (Double.isNaN(mu) || !Double.isFinite(sigma) || sigma < 0.) {
+            return StatsUtil.mlError();
+        }
+        if (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
new file mode 100644
index 0000000000000000000000000000000000000000..2ba6a6271371c136fe6a29a544797de96be0513f
--- /dev/null
+++ b/com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/stats/Rt.java
@@ -0,0 +1,32 @@
+/*
+ * 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 static com.oracle.truffle.r.library.stats.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 {
+    @Override
+    public double evaluate(double df, RandomNumberProvider rand) {
+        if (Double.isNaN(df) || df <= 0.0) {
+            return StatsUtil.mlError();
+        }
+
+        if (!Double.isFinite(df)) {
+            return rand.normRand();
+        } else {
+            return rand.normRand() / Math.sqrt(rchisq(df, rand) / df);
+        }
+    }
+}
diff --git a/com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/stats/Runif.java b/com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/stats/Runif.java
index 0536885f7ec6dbdd5a694c6a4ef9891d8b50ebbe..57a877536fa532404eb5899b115ba11e4c812043 100644
--- a/com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/stats/Runif.java
+++ b/com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/stats/Runif.java
@@ -23,21 +23,18 @@
 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;
 import com.oracle.truffle.r.runtime.RRuntime;
-import com.oracle.truffle.r.runtime.rng.RandomNumberNode;
 
 public final class Runif implements RandFunction2_Double {
-
     @Override
-    public boolean hasCustomRandomGeneration() {
-        return true;
-    }
-
-    @Override
-    public double evaluate(int index, double min, double max, double random, RandomNumberNode randomNode) {
+    public double evaluate(double min, double max, RandomNumberProvider rand) {
         if (!RRuntime.isFinite(min) || !RRuntime.isFinite(max) || max < min) {
             return StatsUtil.mlError();
         }
-        return min + randomNode.executeSingleDouble() * (max - min);
+        if (min == max) {
+            return min;
+        }
+        return min + rand.unifRand() * (max - min);
     }
 }
diff --git a/com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/stats/SExp.java b/com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/stats/SExp.java
new file mode 100644
index 0000000000000000000000000000000000000000..924bbf783c4fd9c35c6caef2ab52e4bf660ef859
--- /dev/null
+++ b/com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/stats/SExp.java
@@ -0,0 +1,81 @@
+/*
+ * 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.api.CompilerDirectives.CompilationFinal;
+import com.oracle.truffle.r.runtime.rng.RandomNumberGenerator;
+
+/**
+ * Generation of random value from standard exponential distribution. Corresponds to {@code sexp.c}
+ * in GnuR.
+ */
+public final class SExp {
+    private SExp() {
+        // only static members
+    }
+
+    /* q[k-1] = sum(log(2)^k / k!) k=1,..,n, */
+    /* The highest n (here 16) is determined by q[n-1] = 1.0 */
+    /* within standard precision */
+    @CompilationFinal(dimensions = 1) private static final double[] q = {
+                    0.6931471805599453,
+                    0.9333736875190459,
+                    0.9888777961838675,
+                    0.9984959252914960,
+                    0.9998292811061389,
+                    0.9999833164100727,
+                    0.9999985691438767,
+                    0.9999998906925558,
+                    0.9999999924734159,
+                    0.9999999995283275,
+                    0.9999999999728814,
+                    0.9999999999985598,
+                    0.9999999999999289,
+                    0.9999999999999968,
+                    0.9999999999999999,
+                    1.0000000000000000
+    };
+
+    public static double expRand(RandomNumberGenerator generator) {
+        double a = 0.;
+        // precaution if u = 0 is ever returned
+        double u = generator.genrandDouble();
+        while (u <= 0. || u >= 1.) {
+            u = generator.genrandDouble();
+        }
+
+        for (;;) {
+            u += u;
+            if (u > 1.) {
+                break;
+            }
+            a += q[0];
+        }
+        u -= 1.;
+
+        if (u <= q[0]) {
+            return a + u;
+        }
+
+        int i = 0;
+        double ustar = generator.genrandDouble();
+        double umin = ustar;
+        do {
+            ustar = generator.genrandDouble();
+            if (umin > ustar) {
+                umin = ustar;
+            }
+            i++;
+        } while (u > q[i]);
+        return a + umin * q[0];
+    }
+}
diff --git a/com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/stats/SNorm.java b/com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/stats/SNorm.java
new file mode 100644
index 0000000000000000000000000000000000000000..0f6737a37571d2144c6858be57453fcbac413ec8
--- /dev/null
+++ b/com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/stats/SNorm.java
@@ -0,0 +1,40 @@
+/*
+ * 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.runtime.RError;
+import com.oracle.truffle.r.runtime.rng.RRNG.NormKind;
+import com.oracle.truffle.r.runtime.rng.RandomNumberGenerator;
+
+/**
+ * Generation of random value from standard normal distribution N(0,1). Corresponds to
+ * {@code snorm.c} in GnuR.
+ */
+public final class SNorm {
+    private SNorm() {
+        // only static members
+    }
+
+    // TODO: implement other normKinds
+
+    private static final double BIG = 134217728; /* 2^27 */
+
+    public static double normRand(RandomNumberGenerator rand, NormKind normKind) {
+        if (normKind != NormKind.INVERSION) {
+            throw RError.nyi(null, "unifNorm(): no other NormKind than the default INVERSION is implemented");
+        }
+        /* unif_rand() alone is not of high enough precision */
+        double u1 = rand.genrandDouble();
+        u1 = (int) (BIG * u1) + rand.genrandDouble();
+        return Random2.qnorm5(u1 / BIG, 0.0, 1.0, true, false);
+    }
+}
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
new file mode 100644
index 0000000000000000000000000000000000000000..422d76cb6f7c006a3e94ad3779e76fc6d9cfb0b2
--- /dev/null
+++ b/com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/stats/Signrank.java
@@ -0,0 +1,53 @@
+/*
+ * 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) 1999--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.forceint;
+
+import com.oracle.truffle.r.library.stats.RandGenerationFunctions.RandFunction1_Double;
+import com.oracle.truffle.r.library.stats.RandGenerationFunctions.RandomNumberProvider;
+
+public final class Signrank {
+
+    public static final class RSignrank implements RandFunction1_Double {
+        @Override
+        public double evaluate(double n, RandomNumberProvider rand) {
+            int i;
+            int k;
+            double r;
+
+            if (Double.isNaN(n)) {
+                return n;
+            }
+            if (Double.isInfinite(n)) {
+                // 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 ? StatsUtil.mlError() : 0;
+            }
+
+            n = forceint(n);
+            if (n < 0) {
+                return StatsUtil.mlError();
+            }
+
+            if (n == 0) {
+                return 0;
+            }
+            r = 0.0;
+            k = (int) n;
+            for (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/StatsUtil.java b/com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/stats/StatsUtil.java
index 76fe2473335bca7fd404efc89a49945704360171..7a5348110e6dcddb2b05578952f40a334ac2f354 100644
--- a/com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/stats/StatsUtil.java
+++ b/com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/stats/StatsUtil.java
@@ -12,6 +12,8 @@
  */
 package com.oracle.truffle.r.library.stats;
 
+import static com.oracle.truffle.r.library.stats.LBeta.lbeta;
+
 import com.oracle.truffle.api.CompilerDirectives.CompilationFinal;
 import com.oracle.truffle.api.CompilerDirectives.TruffleBoundary;
 
@@ -119,6 +121,17 @@ public class StatsUtil {
         return giveLog ? -0.5 * Math.log(f) + x : Math.exp(x) / Math.sqrt(f);
     }
 
+    public static double lfastchoose(double n, double k) {
+        return -Math.log(n + 1.) - lbeta(n - k + 1., k + 1.);
+    }
+
+    public static double fsign(double x, double y) {
+        if (Double.isNaN(x) || Double.isNaN(y)) {
+            return x + y;
+        }
+        return ((y >= 0) ? TOMS708.fabs(x) : -TOMS708.fabs(x));
+    }
+
     //
     // GNUR from fmin2.c and fmax2
     //
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 d1ddd7ab798fad0019530278e8c1fb32355175a2..a61e44b42201c5c5af425fa83c95fd84718d8e8f 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
@@ -67,7 +67,7 @@ public class TOMS708 {
         return Math.exp(v);
     }
 
-    private static double fabs(double v) {
+    public static double fabs(double v) {
         return Math.abs(v);
     }
 
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
new file mode 100644
index 0000000000000000000000000000000000000000..006474114406a883f3eecd34dd174f20d8c847b0
--- /dev/null
+++ b/com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/stats/Wilcox.java
@@ -0,0 +1,74 @@
+/*
+ * 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) 1999--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.runtime.RError.Message.CALLOC_COULD_NOT_ALLOCATE_INF;
+
+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.RError;
+import com.oracle.truffle.r.runtime.RRuntime;
+
+public final class Wilcox {
+
+    public static final class RWilcox implements RandFunction2_Double {
+        @Override
+        public double evaluate(double m, double n, 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.isFinite(m) || !Double.isFinite(n)) {
+                // 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);
+            if ((m < 0) || (n < 0)) {
+                // TODO: for some reason the macro in GNUR here returns NA instead of NaN...
+                // return StatsUtil.mlError();
+                return RRuntime.DOUBLE_NA;
+            }
+
+            if ((m == 0) || (n == 0)) {
+                return (0);
+            }
+
+            r = 0.0;
+            k = (int) (m + n);
+
+            int[] x;
+            try {
+                x = new int[k];
+            } catch (OutOfMemoryError ex) {
+                // GnuR seems to be reporting the same number regardless of 'k'
+                throw RError.error(RError.SHOW_CALLER, CALLOC_COULD_NOT_ALLOCATE_INF);
+            }
+            for (i = 0; i < k; i++) {
+                x[i] = i;
+            }
+            for (i = 0; i < n; i++) {
+                j = (int) Math.floor(k * rand.unifRand());
+                r += x[j];
+                x[j] = x[--k];
+            }
+            return (r - n * (n - 1) / 2);
+        }
+    }
+}
diff --git a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/AsComplex.java b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/AsComplex.java
index 56de0ead0465957c4b675379c08bdefe7d3d360e..d62792b3b69f6136611edd494fd1b510a695db74 100644
--- a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/AsComplex.java
+++ b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/AsComplex.java
@@ -29,12 +29,13 @@ import com.oracle.truffle.api.dsl.Specialization;
 import com.oracle.truffle.api.profiles.ConditionProfile;
 import com.oracle.truffle.r.nodes.builtin.CastBuilder;
 import com.oracle.truffle.r.nodes.builtin.RBuiltinNode;
+import com.oracle.truffle.r.runtime.RDispatch;
 import com.oracle.truffle.r.runtime.builtins.RBuiltin;
 import com.oracle.truffle.r.runtime.data.RDataFactory;
 import com.oracle.truffle.r.runtime.data.RNull;
 import com.oracle.truffle.r.runtime.data.model.RAbstractComplexVector;
 
-@RBuiltin(name = "as.complex", kind = PRIMITIVE, parameterNames = {"x", "..."}, behavior = PURE)
+@RBuiltin(name = "as.complex", kind = PRIMITIVE, dispatch = RDispatch.INTERNAL_GENERIC, parameterNames = {"x", "..."}, behavior = PURE)
 public abstract class AsComplex extends RBuiltinNode {
 
     private final ConditionProfile noAttributes = ConditionProfile.createBinaryProfile();
diff --git a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/UpdateDim.java b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/UpdateDim.java
index 30235da0adb9f3125103907dbce6ebfd1e7d5edb..0b7c49004d52e746b872d503f89b2e7fa32376aa 100644
--- a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/UpdateDim.java
+++ b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/UpdateDim.java
@@ -29,12 +29,17 @@ 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.r.nodes.attributes.SetFixedAttributeNode;
+import com.oracle.truffle.api.object.DynamicObject;
+import com.oracle.truffle.api.profiles.ConditionProfile;
 import com.oracle.truffle.r.nodes.attributes.InitAttributesNode;
+import com.oracle.truffle.r.nodes.attributes.SetFixedAttributeNode;
 import com.oracle.truffle.r.nodes.builtin.CastBuilder;
 import com.oracle.truffle.r.nodes.builtin.RBuiltinNode;
 import com.oracle.truffle.r.nodes.function.opt.ReuseNonSharedNode;
+import com.oracle.truffle.r.runtime.RRuntime;
 import com.oracle.truffle.r.runtime.builtins.RBuiltin;
+import com.oracle.truffle.r.runtime.data.RAttributeStorage;
+import com.oracle.truffle.r.runtime.data.RAttributesLayout;
 import com.oracle.truffle.r.runtime.data.RIntVector;
 import com.oracle.truffle.r.runtime.data.RNull;
 import com.oracle.truffle.r.runtime.data.RVector;
@@ -61,8 +66,8 @@ public abstract class UpdateDim extends RBuiltinNode {
 
     @Specialization
     protected RAbstractVector updateDim(RAbstractVector vector, RAbstractIntVector dimensions,
-                    @Cached("createDim()") SetFixedAttributeNode putDimensions,
-                    @Cached("create()") InitAttributesNode initAttributes) {
+                    @Cached("createBinaryProfile()") ConditionProfile initAttrProfile,
+                    @Cached("createDim()") SetFixedAttributeNode putDimensions) {
         RIntVector dimensionsMaterialized = dimensions.materialize();
         int[] dimsData = dimensionsMaterialized.getDataCopy();
         RVector.verifyDimensions(vector.getLength(), dimsData, this);
@@ -70,7 +75,14 @@ public abstract class UpdateDim extends RBuiltinNode {
         result.setInternalDimensions(dimsData);
         result.setInternalNames(null);
         result.setInternalDimNames(null);
-        putDimensions.execute(initAttributes.execute(result), dimensionsMaterialized);
+
+        DynamicObject attrs = result.getAttributes();
+        if (initAttrProfile.profile(attrs == null)) {
+            attrs = RAttributesLayout.createDim(dimensionsMaterialized);
+            result.initAttributes(attrs);
+        } else {
+            putDimensions.execute(attrs, dimensionsMaterialized);
+        }
         return result;
     }
 }
diff --git a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/foreign/ForeignFunctions.java b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/foreign/ForeignFunctions.java
index ffd118e823b031e10a8c0bd8cd9cf4191ef593a3..59786926cd8806b63b998768c62575be03c53fb2 100644
--- a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/foreign/ForeignFunctions.java
+++ b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/foreign/ForeignFunctions.java
@@ -55,14 +55,29 @@ import com.oracle.truffle.r.library.stats.Qbinom;
 import com.oracle.truffle.r.library.stats.Qnorm;
 import com.oracle.truffle.r.library.stats.RBeta;
 import com.oracle.truffle.r.library.stats.RCauchy;
+import com.oracle.truffle.r.library.stats.RChisq;
+import com.oracle.truffle.r.library.stats.RExp;
+import com.oracle.truffle.r.library.stats.RGamma;
+import com.oracle.truffle.r.library.stats.RGeom;
+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.RandGenerationFunctionsFactory;
 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.StatsFunctionsFactory;
 import com.oracle.truffle.r.library.stats.StatsUtil;
+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;
 import com.oracle.truffle.r.library.tools.Rmd5NodeGen;
@@ -354,8 +369,36 @@ public class ForeignFunctions {
                     return RandGenerationFunctionsFactory.Function2_DoubleNodeGen.create(new Runif());
                 case "rbeta":
                     return RandGenerationFunctionsFactory.Function2_DoubleNodeGen.create(new RBeta());
+                case "rgamma":
+                    return RandGenerationFunctionsFactory.Function2_DoubleNodeGen.create(new RGamma());
                 case "rcauchy":
                     return RandGenerationFunctionsFactory.Function2_DoubleNodeGen.create(new RCauchy());
+                case "rf":
+                    return RandGenerationFunctionsFactory.Function2_DoubleNodeGen.create(new Rf());
+                case "rlogis":
+                    return RandGenerationFunctionsFactory.Function2_DoubleNodeGen.create(new RLogis());
+                case "rweibull":
+                    return RandGenerationFunctionsFactory.Function2_DoubleNodeGen.create(new RWeibull());
+                case "rnchisq":
+                    return RandGenerationFunctionsFactory.Function2_DoubleNodeGen.create(new RNchisq());
+                case "rnbinom_mu":
+                    return RandGenerationFunctionsFactory.Function2_DoubleNodeGen.create(new RNbinomMu());
+                case "rwilcox":
+                    return RandGenerationFunctionsFactory.Function2_IntNodeGen.create(new RWilcox());
+                case "rchisq":
+                    return RandGenerationFunctionsFactory.Function1_DoubleNodeGen.create(new RChisq());
+                case "rexp":
+                    return RandGenerationFunctionsFactory.Function1_DoubleNodeGen.create(new RExp());
+                case "rgeom":
+                    return RandGenerationFunctionsFactory.Function1_IntNodeGen.create(new RGeom());
+                case "rpois":
+                    return RandGenerationFunctionsFactory.Function1_IntNodeGen.create(new RPois());
+                case "rt":
+                    return RandGenerationFunctionsFactory.Function1_DoubleNodeGen.create(new Rt());
+                case "rsignrank":
+                    return RandGenerationFunctionsFactory.Function1_IntNodeGen.create(new RSignrank());
+                case "rhyper":
+                    return RandGenerationFunctionsFactory.Function3_IntNodeGen.create(new RHyper());
                 case "qgamma":
                     return StatsFunctionsFactory.Function3_2NodeGen.create(new QgammaFunc());
                 case "dbinom":
@@ -368,6 +411,8 @@ public class ForeignFunctions {
                     return StatsFunctionsFactory.Function3_2NodeGen.create(new Pbinom());
                 case "pf":
                     return StatsFunctionsFactory.Function3_2NodeGen.create(new Pf());
+                case "rmultinom":
+                    return RMultinomNodeGen.create();
                 case "Approx":
                     return StatsFunctionsFactory.ApproxNodeGen.create();
                 case "ApproxTest":
diff --git a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/fastr/FastRTry.java b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/fastr/FastRTry.java
index 071ef08d2a93304f80ef7f32d0c3661722fef431..315f1f2c0aad2161732c7d25cb6d09620e3a958d 100644
--- a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/fastr/FastRTry.java
+++ b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/fastr/FastRTry.java
@@ -33,6 +33,7 @@ import com.oracle.truffle.r.nodes.builtin.RBuiltinNode;
 import com.oracle.truffle.r.nodes.function.RCallBaseNode;
 import com.oracle.truffle.r.nodes.function.RCallNode;
 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.RArgsValuesAndNames;
 import com.oracle.truffle.r.runtime.data.RFunction;
@@ -55,7 +56,7 @@ public abstract class FastRTry extends RBuiltinNode {
             frame.setObject(frameSlot, RArgsValuesAndNames.EMPTY);
             call.execute(frame, func);
         } catch (Throwable ex) {
-            return String.format("Exception %s, message: %s", ex.getClass().getSimpleName(), ex.getMessage());
+            return Utils.stringFormat("Exception %s, message: %s", ex.getClass().getSimpleName(), ex.getMessage());
         } finally {
             frame.setObject(frameSlot, null);
         }
diff --git a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/access/vector/CachedExtractVectorNode.java b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/access/vector/CachedExtractVectorNode.java
index 58ebcbd2f1f0d1dc70a8377f778ee1f839cbbbb4..9013ee971727f511d890c57a113796f664921721 100644
--- a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/access/vector/CachedExtractVectorNode.java
+++ b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/access/vector/CachedExtractVectorNode.java
@@ -433,7 +433,6 @@ final class CachedExtractVectorNode extends CachedVectorNode {
 
     protected abstract static class SetNamesNode extends Node {
 
-        @Child private SetFixedAttributeNode namesAttrSetter = SetFixedAttributeNode.createNames();
         @Child private GetFixedAttributeNode namesAttrGetter = GetFixedAttributeNode.createNames();
 
         public abstract void execute(RVector<?> container, Object newNames);
@@ -446,7 +445,6 @@ final class CachedExtractVectorNode extends CachedVectorNode {
             if (container.getAttributes() == null) {
                 // usual case
                 container.initAttributes(RAttributesLayout.createNames(newNames1));
-                namesAttrSetter.execute(container.initAttributes(), newNames1);
                 container.setInternalNames(newNames1);
             } else {
                 // from an RLanguage extraction that set a name
diff --git a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/attributes/GetAttributeNode.java b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/attributes/GetAttributeNode.java
index 0b17a7994b921da280aa3ea00a6a16867888980c..0a28d002af32b82684ecf48e4f815256e363c859 100644
--- a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/attributes/GetAttributeNode.java
+++ b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/attributes/GetAttributeNode.java
@@ -28,6 +28,7 @@ import com.oracle.truffle.api.dsl.Specialization;
 import com.oracle.truffle.api.object.DynamicObject;
 import com.oracle.truffle.api.object.Location;
 import com.oracle.truffle.api.object.Shape;
+import com.oracle.truffle.api.profiles.ConditionProfile;
 
 public abstract class GetAttributeNode extends AttributeAccessNode {
 
@@ -41,14 +42,14 @@ public abstract class GetAttributeNode extends AttributeAccessNode {
     public abstract Object execute(DynamicObject attrs, String name);
 
     @Specialization(limit = "3", //
-                    guards = {"location != null", "cachedName.equals(name)", "shapeCheck(shape, attrs)"}, //
+                    guards = {"cachedName.equals(name)", "shapeCheck(shape, attrs)"}, //
                     assumptions = {"shape.getValidAssumption()"})
     @SuppressWarnings("unused")
     protected Object getAttrCached(DynamicObject attrs, String name,
                     @Cached("name") String cachedName,
                     @Cached("lookupShape(attrs)") Shape shape,
                     @Cached("lookupLocation(shape, name)") Location location) {
-        return location.get(attrs);
+        return location == null ? null : location.get(attrs);
     }
 
     @TruffleBoundary
diff --git a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/attributes/GetFixedAttributeNode.java b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/attributes/GetFixedAttributeNode.java
index 4fae16c6d818c83d57bfb68edc92e54bdd45bf7e..35b79c0d788b2e5f0ac8b45900b880778437d283 100644
--- a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/attributes/GetFixedAttributeNode.java
+++ b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/attributes/GetFixedAttributeNode.java
@@ -28,6 +28,7 @@ import com.oracle.truffle.api.dsl.Specialization;
 import com.oracle.truffle.api.object.DynamicObject;
 import com.oracle.truffle.api.object.Location;
 import com.oracle.truffle.api.object.Shape;
+import com.oracle.truffle.api.profiles.ConditionProfile;
 import com.oracle.truffle.r.runtime.RRuntime;
 
 public abstract class GetFixedAttributeNode extends FixedAttributeAccessNode {
@@ -54,14 +55,18 @@ public abstract class GetFixedAttributeNode extends FixedAttributeAccessNode {
 
     public abstract Object execute(DynamicObject attrs);
 
+    protected boolean hasProperty(Shape shape) {
+        return shape.hasProperty(name);
+    }
+
     @Specialization(limit = "3", //
-                    guards = {"shapeCheck(shape, attrs)", "location != null"}, //
+                    guards = {"shapeCheck(shape, attrs)"}, //
                     assumptions = {"shape.getValidAssumption()"})
     @SuppressWarnings("unused")
     protected Object getAttrCached(DynamicObject attrs,
                     @Cached("lookupShape(attrs)") Shape shape,
                     @Cached("lookupLocation(shape, name)") Location location) {
-        return location.get(attrs);
+        return location == null ? null : location.get(attrs);
     }
 
     @Specialization(contains = "getAttrCached")
diff --git a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/attributes/RemoveFixedAttributeNode.java b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/attributes/RemoveFixedAttributeNode.java
index f70e497be2d07bd802c248d5e44bf88012d2f418..5d41dae1dbc3861f24152719abd03b86707050e0 100644
--- a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/attributes/RemoveFixedAttributeNode.java
+++ b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/attributes/RemoveFixedAttributeNode.java
@@ -28,6 +28,7 @@ import com.oracle.truffle.api.dsl.Specialization;
 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.r.runtime.RRuntime;
 
 public abstract class RemoveFixedAttributeNode extends FixedAttributeAccessNode {
@@ -59,13 +60,15 @@ public abstract class RemoveFixedAttributeNode extends FixedAttributeAccessNode
     public abstract void execute(DynamicObject attrs);
 
     @Specialization(limit = "3", //
-                    guards = {"shapeCheck(shape, attrs)", "property != null"}, //
+                    guards = {"shapeCheck(shape, attrs)"}, //
                     assumptions = {"shape.getValidAssumption()"})
     protected void removeAttrCached(DynamicObject attrs,
                     @Cached("lookupShape(attrs)") Shape shape,
                     @Cached("lookupProperty(shape, name)") Property property) {
-        Shape newShape = attrs.getShape().removeProperty(property);
-        attrs.setShapeAndResize(shape, newShape);
+        if (property != null) {
+            Shape newShape = attrs.getShape().removeProperty(property);
+            attrs.setShapeAndResize(shape, newShape);
+        }
     }
 
     @Specialization(contains = "removeAttrCached")
diff --git a/com.oracle.truffle.r.parser/src/com/oracle/truffle/r/parser/ParserGeneration.java b/com.oracle.truffle.r.parser/src/com/oracle/truffle/r/parser/ParserGeneration.java
index 8b3a03ea114ad98b6f1854bd59dea84f2d81c5d4..4723391c1cf5ffb854e54e93e1f782cbb0120e17 100644
--- a/com.oracle.truffle.r.parser/src/com/oracle/truffle/r/parser/ParserGeneration.java
+++ b/com.oracle.truffle.r.parser/src/com/oracle/truffle/r/parser/ParserGeneration.java
@@ -85,6 +85,8 @@ public class ParserGeneration {
         "remove deprecated calls to SourceSection functions",
         "remove deprecated calls to Source functions",
         "remove restricion on fixed number of digits in UTF codes",
-        "support ? for help"
+        "support ? for help",
+        "support for hex float literals",
+        "support for hex float literals without decimal point: 0x0p0",
     };
 }
diff --git a/com.oracle.truffle.r.parser/src/com/oracle/truffle/r/parser/R.g b/com.oracle.truffle.r.parser/src/com/oracle/truffle/r/parser/R.g
index 96a9d90de458ee62c5ab7350cae8aaaf0d8ca742..78c92fcb0f7257ea1525b48384da9a7573b3ba7e 100644
--- a/com.oracle.truffle.r.parser/src/com/oracle/truffle/r/parser/R.g
+++ b/com.oracle.truffle.r.parser/src/com/oracle/truffle/r/parser/R.g
@@ -575,13 +575,13 @@ INTEGER
 COMPLEX
     : ('0'..'9')+ '.' ('0'..'9')* EXPONENT? 'i' { setText(getText().substring(0, getText().length()-1)); }
     | '.'? ('0'..'9')+ EXPONENT? 'i' { setText(getText().substring(0, getText().length()-1)); }
-    | '0x' HEX_DIGIT 'i' { setText(getText().substring(0, getText().length()-1)); }
+    | '0x' HEX_DIGIT+ ('.'? HEX_DIGIT* HEX_EXPONENT)? 'i' { setText(getText().substring(0, getText().length()-1)); }
     ;
 
 DOUBLE
     : ('0'..'9')+ '.' ('0'..'9')* EXPONENT?
     | '.'? ('0'..'9')+ EXPONENT?
-    | '0x' HEX_DIGIT+
+    | '0x' HEX_DIGIT+ ('.'? HEX_DIGIT* HEX_EXPONENT)?
     ;
 
 DD : '..' ('0'..'9')+ ;
@@ -660,6 +660,7 @@ fragment LINE_BREAK
     ;
 
 fragment EXPONENT : ('e'|'E') ('+'|'-')? ('0'..'9')+ ;
+fragment HEX_EXPONENT : ('p'|'P') ('+'|'-')? ('0'..'9')+ ;
 
 fragment OP_NAME
     : ID_NAME
diff --git a/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/RDeparse.java b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/RDeparse.java
index 9783f4d7d95f9847a9798e1ccf5f5b318f2a775b..7b1f94e0f16223e3ace87561049a8e541501a391 100644
--- a/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/RDeparse.java
+++ b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/RDeparse.java
@@ -153,7 +153,7 @@ public class RDeparse {
                     new Func("+", null, new PPInfo(PP.BINARY, PREC_SUM, false)),
                     new Func("-", null, new PPInfo(PP.BINARY, PREC_SUM, false)),
                     new Func("*", null, new PPInfo(PP.BINARY, PREC_PROD, false)),
-                    new Func("/", null, new PPInfo(PP.BINARY, PREC_PROD, false)),
+                    new Func("/", null, new PPInfo(PP.BINARY2, PREC_PROD, false)),
                     new Func("^", null, new PPInfo(PP.BINARY2, PREC_POWER, false)),
                     new Func("%%", null, new PPInfo(PP.BINARY, PREC_PERCENT, false)),
                     new Func("%/%", null, new PPInfo(PP.BINARY, PREC_PERCENT, false)),
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 38c7c2c87dad331f515cb30d81b1f9520637bb23..60e498c60ee86bacb2f327409f5b0dc46f36c249 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
@@ -342,6 +342,8 @@ public final class RError extends RuntimeException {
         INVALID_FIRST_FILENAME("invalid first filename"),
         INVALID_SECOND_FILENAME("invalid second filename"),
         INVALID_FIRST_ARGUMENT("invalid first argument"),
+        INVALID_FIRST_ARGUMENT_NAME("invalid first argument '%s'"),
+        INVALID_SECOND_ARGUMENT_NAME("invalid second argument '%s'"),
         NO_ENCLOSING_ENVIRONMENT("no enclosing environment"),
         ASSIGN_EMPTY("cannot assign values in the empty environment"),
         USE_NULL_ENV_DEFUNCT("use of NULL environment is defunct"),
@@ -457,6 +459,7 @@ public final class RError extends RuntimeException {
         UNUSED_ARGUMENT("unused argument (%s)"),
         UNUSED_ARGUMENTS("unused arguments (%s)"),
         INFINITE_MISSING_VALUES("infinite or missing values in '%s'"),
+        CALLOC_COULD_NOT_ALLOCATE_INF("'Calloc' could not allocate memory (18446744071562067968 of 4 bytes)"),
         NON_SQUARE_MATRIX("non-square matrix in '%s'"),
         LAPACK_ERROR("error code %d from Lapack routine '%s'"),
         VALUE_OUT_OF_RANGE("value out of range in '%s'"),
@@ -522,6 +525,7 @@ public final class RError extends RuntimeException {
         INCORRECT_NUM_PROB("incorrect number of probabilities"),
         NA_IN_PROB_VECTOR("NA in probability vector"),
         NEGATIVE_PROBABILITY("negative probability"),
+        NO_POSITIVE_PROBABILITIES("no positive probabilities"),
         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"),
diff --git a/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/rng/RNGInitAdapter.java b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/rng/RNGInitAdapter.java
index e0eeb827214237504345ef90b0d8fe2f98849e83..ca4a665de1e1940abf16686e7411b8bab8060319 100644
--- a/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/rng/RNGInitAdapter.java
+++ b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/rng/RNGInitAdapter.java
@@ -11,21 +11,36 @@
  */
 package com.oracle.truffle.r.runtime.rng;
 
+/**
+ * Manages the iSeed array for generators and contains some useful common code.
+ */
 public abstract class RNGInitAdapter implements RandomNumberGenerator {
 
     protected static final double I2_32M1 = 2.3283064365386963e-10;
+    protected static final int MAX_ISEED_SIZE = 625;
 
     // TODO: it seems like GNU R this is shared between the generators (does it matter?)
-    protected final int[] iSeed = new int[625];
+    private int[] iSeed = new int[MAX_ISEED_SIZE + 1];
 
     @Override
     public void setISeed(int[] seeds) {
-        for (int i = 1; i <= getNSeed(); i++) {
-            iSeed[i - 1] = seeds[i];
-        }
+        iSeed = seeds;
         fixupSeeds(false);
     }
 
+    @Override
+    public final int[] getSeeds() {
+        return iSeed;
+    }
+
+    protected final int getISeedItem(int index) {
+        return iSeed[index + 1];
+    }
+
+    protected final void setISeedItem(int index, int value) {
+        iSeed[index + 1] = value;
+    }
+
     /**
      * Ensure 0 and 1 are never returned from rand generation algorithm.
      */
diff --git a/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/rng/RRNG.java b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/rng/RRNG.java
index 56ab040453ffb9cfe867a2aed314fdfccd1876f8..28b845bc33c215403cf214cfd2a27a4a58ff08e1 100644
--- a/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/rng/RRNG.java
+++ b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/rng/RRNG.java
@@ -41,6 +41,9 @@ import com.oracle.truffle.r.runtime.rng.user.UserRNG;
  * uncontrolled way, which then has to be checked. Currently we do not support reading it, although
  * we do create/update it when the seed/kind is changed, primarily as a debugging aid. N.B. GnuR
  * updates it on <i>every</i> random number generation!
+ *
+ * Important note: make sure to invoke {@link #getRNGState()} before invoking any other methods from
+ * this class and to invoke {@link #putRNGState()} when done witch random number generation.
  */
 public class RRNG {
     /**
@@ -190,11 +193,11 @@ public class RRNG {
         return getContextState().currentGenerator.getKind();
     }
 
-    static RandomNumberGenerator currentGenerator() {
+    public static RandomNumberGenerator currentGenerator() {
         return getContextState().currentGenerator;
     }
 
-    private static NormKind currentNormKind() {
+    public static NormKind currentNormKind() {
         return getContextState().currentNormKind;
     }
 
@@ -381,6 +384,10 @@ public class RRNG {
             } else if (seedsObj instanceof RIntVector) {
                 RIntVector seedsVec = (RIntVector) seedsObj;
                 seeds = seedsVec.getDataWithoutCopying();
+                if (seeds == currentGenerator().getSeeds()) {
+                    // no change of the .Random.seed variable
+                    return;
+                }
             } else {
                 // seedsObj is not valid, which should have been reported and fixed in getRNGKind
                 return;
@@ -404,26 +411,8 @@ public class RRNG {
     @TruffleBoundary
     public static void putRNGState() {
         int[] seeds = currentGenerator().getSeeds();
-        int lenSeeds = currentGenerator().getNSeed();
-
-        // we update the existing vector from global env if possible
-        int[] data;
-        Object prevState = getDotRandomSeed();
-        boolean canReusePrev = prevState instanceof RIntVector && ((RIntVector) prevState).getLength() == lenSeeds + 1 && !((RIntVector) prevState).isShared();
-        if (canReusePrev) {
-            data = ((RIntVector) prevState).getDataWithoutCopying();
-        } else {
-            data = new int[lenSeeds + 1];
-        }
-
-        data[0] = currentKind().ordinal() + 100 * currentNormKind().ordinal();
-        for (int i = 0; i < lenSeeds; i++) {
-            data[i + 1] = seeds[i];
-        }
-
-        if (!canReusePrev) {
-            RIntVector vector = RDataFactory.createIntVector(data, RDataFactory.COMPLETE_VECTOR);
-            REnvironment.globalEnv().safePut(RANDOM_SEED, vector);
-        }
+        seeds[0] = currentKind().ordinal() + 100 * currentNormKind().ordinal();
+        RIntVector vector = RDataFactory.createIntVector(seeds, RDataFactory.COMPLETE_VECTOR);
+        REnvironment.globalEnv().safePut(RANDOM_SEED, vector.makeSharedPermanent());
     }
 }
diff --git a/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/rng/RandomNumberGenerator.java b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/rng/RandomNumberGenerator.java
index 3ca1a0f164238b5dd15d32ab1029ce9147346602..8be86f72a0f4937cd75d90a813de593f2ea03e90 100644
--- a/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/rng/RandomNumberGenerator.java
+++ b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/rng/RandomNumberGenerator.java
@@ -21,6 +21,10 @@ public interface RandomNumberGenerator {
 
     void fixupSeeds(boolean initial);
 
+    /**
+     * Returns array in the format of .Random.seed, i.e. under index 0 is id of the generator and
+     * the rest are the actual seeds.
+     */
     int[] getSeeds();
 
     double genrandDouble();
@@ -34,7 +38,8 @@ public interface RandomNumberGenerator {
 
     /**
      * Sets array which contains current generator flag under index 0 and seeds for random
-     * generation under the other indices.
+     * generation under the other indices. The generator may use the array as is without making a
+     * defensive copy, the caller must make sure the array contents do not get changed.
      */
     void setISeed(int[] seeds);
 }
diff --git a/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/rng/mm/MarsagliaMulticarry.java b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/rng/mm/MarsagliaMulticarry.java
index 697e3c65ac7ca598bbbd35eef9571477566915a8..34a99d4b2dd3af536988be92f5aff6509eea1f04 100644
--- a/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/rng/mm/MarsagliaMulticarry.java
+++ b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/rng/mm/MarsagliaMulticarry.java
@@ -26,7 +26,7 @@ public final class MarsagliaMulticarry extends RNGInitAdapter {
         int seed = seedParam;
         for (int i = 0; i < getNSeed(); i++) {
             seed = (69069 * seed + 1);
-            iSeed[i] = seed;
+            setISeedItem(i, seed);
         }
         fixupSeeds(true);
     }
@@ -34,29 +34,24 @@ public final class MarsagliaMulticarry extends RNGInitAdapter {
     @Override
     @TruffleBoundary
     public void fixupSeeds(boolean initial) {
-        if (iSeed[0] == 0) {
-            iSeed[0] = 1;
+        if (getISeedItem(0) == 0) {
+            setISeedItem(0, 1);
         }
-        if (iSeed[1] == 0) {
-            iSeed[1] = 1;
+        if (getISeedItem(1) == 0) {
+            setISeedItem(1, 1);
         }
     }
 
-    @Override
-    public int[] getSeeds() {
-        return iSeed;
-    }
-
     @Override
     public double genrandDouble() {
-        int state0 = iSeed[0];
-        int state1 = iSeed[1];
+        int state0 = getISeedItem(0);
+        int state1 = getISeedItem(1);
         state0 = 36969 * (state0 & 0177777) + (state0 >>> 16);
         state1 = 18000 * (state1 & 0177777) + (state1 >>> 16);
         int x = (state0 << 16) ^ (state1 & 0177777);
         double d = (x & 0xffffffffL) * I2_32M1;
-        iSeed[0] = state0;
-        iSeed[1] = state1;
+        setISeedItem(0, state0);
+        setISeedItem(1, state1);
         return fixup(d); /* in [0,1) */
     }
 
diff --git a/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/rng/mt/MersenneTwister.java b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/rng/mt/MersenneTwister.java
index b084498c040d708c01f8e64c056f9a29a29ff9c2..1bccf6eb4b973a527f1af77f564e3f2528df80ca 100644
--- a/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/rng/mt/MersenneTwister.java
+++ b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/rng/mt/MersenneTwister.java
@@ -64,7 +64,6 @@
 package com.oracle.truffle.r.runtime.rng.mt;
 
 import com.oracle.truffle.api.CompilerDirectives.TruffleBoundary;
-import com.oracle.truffle.r.runtime.RInternalError;
 import com.oracle.truffle.r.runtime.rng.RNGInitAdapter;
 import com.oracle.truffle.r.runtime.rng.RRNG;
 import com.oracle.truffle.r.runtime.rng.RRNG.Kind;
@@ -95,36 +94,18 @@ public final class MersenneTwister extends RNGInitAdapter {
      * pointer arithmetic to set {@code mt} to {@code dummy + 1}.
      */
     private int getMt(int i) {
-        return iSeed[i + 1];
+        return getISeedItem(i + 1);
     }
 
     private void setMt(int i, int val) {
-        iSeed[i + 1] = val;
+        setISeedItem(i + 1, val);
     }
 
-    // to keep variable naming (somewhat) consistent with GNU R
-    private int[] dummy = iSeed;
-
     @Override
     public void setISeed(int[] seeds) {
-        boolean changed = false;
-        for (int i = 1; i <= getNSeed(); i++) {
-            changed |= iSeed[i - 1] != seeds[i];
-            iSeed[i - 1] = seeds[i];
-        }
         fixupSeeds(false);
-        // kill the current buffer if seed changes
-        if (changed) {
-            bufferIndex = BUFFER_SIZE;
-        }
-    }
-
-    /**
-     * We have to recreate the effect of having the number of seeds in the array.
-     */
-    @Override
-    public int[] getSeeds() {
-        return iSeed;
+        // kill the current buffer if the seed changes
+        bufferIndex = BUFFER_SIZE;
     }
 
     /**
@@ -141,7 +122,7 @@ public final class MersenneTwister extends RNGInitAdapter {
         int seed = seedParam;
         for (int i = 0; i < getNSeed(); i++) {
             seed = (69069 * seed + 1);
-            iSeed[i] = seed;
+            setISeedItem(i, seed);
         }
         fixupSeeds(true);
         bufferIndex = BUFFER_SIZE;
@@ -151,14 +132,14 @@ public final class MersenneTwister extends RNGInitAdapter {
     @TruffleBoundary
     public void fixupSeeds(boolean initial) {
         if (initial) {
-            iSeed[0] = N;
+            setISeedItem(0, N);
         }
-        if (iSeed[0] <= 0) {
-            iSeed[0] = N;
+        if (getISeedItem(0) <= 0) {
+            setISeedItem(0, N);
         }
         boolean notAllZero = false;
         for (int i = 1; i <= N; i++) {
-            if (iSeed[i] != 0) {
+            if (getISeedItem(i) != 0) {
                 notAllZero = true;
             }
         }
@@ -173,12 +154,11 @@ public final class MersenneTwister extends RNGInitAdapter {
     @Override
     public double genrandDouble() {
         if (bufferIndex == BUFFER_SIZE) {
-            int localDummy0 = dummy[0];
+            int localDummy0 = getISeedItem(0);
             int localMti = localDummy0;
             // It appears that this never happens
             // sgenrand(4357);
-            RInternalError.guarantee(localMti != N + 1);
-
+            assert localMti != N + 1;
             int pos = 0;
             while (true) {
                 int loopCount = Math.min(BUFFER_SIZE - pos, N - localMti);
@@ -216,7 +196,7 @@ public final class MersenneTwister extends RNGInitAdapter {
                 localMti = 0;
             }
             localDummy0 = localMti;
-            dummy[0] = localDummy0;
+            setISeedItem(0, localDummy0);
             bufferIndex = 0;
         }
         return buffer[bufferIndex++];
diff --git a/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/rng/user/UserRNG.java b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/rng/user/UserRNG.java
index 79a8117b3b8c6acc7554842a53d368ffc3baf2c0..84187071f92296f69c96bec987616bcefd1d0270 100644
--- a/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/rng/user/UserRNG.java
+++ b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/rng/user/UserRNG.java
@@ -28,13 +28,13 @@ import com.oracle.truffle.r.runtime.ffi.DLL;
 import com.oracle.truffle.r.runtime.ffi.DLL.DLLInfo;
 import com.oracle.truffle.r.runtime.ffi.RFFIFactory;
 import com.oracle.truffle.r.runtime.ffi.UserRngRFFI;
-import com.oracle.truffle.r.runtime.rng.RNGInitAdapter;
 import com.oracle.truffle.r.runtime.rng.RRNG.Kind;
+import com.oracle.truffle.r.runtime.rng.RandomNumberGenerator;
 
 /**
  * Interface to a user-supplied RNG.
  */
-public final class UserRNG extends RNGInitAdapter {
+public final class UserRNG implements RandomNumberGenerator {
     private static final boolean OPTIONAL = true;
 
     public enum Function {
@@ -124,8 +124,10 @@ public final class UserRNG extends RNGInitAdapter {
         if (!Function.Seedloc.isDefined()) {
             return null;
         }
-        int[] result = new int[nSeeds];
-        userRngRFFI.seeds(result);
+        int[] seeds = new int[nSeeds];
+        userRngRFFI.seeds(seeds);
+        int[] result = new int[nSeeds + 1];
+        System.arraycopy(seeds, 0, result, 1, seeds.length);
         return result;
     }
 
@@ -144,4 +146,9 @@ public final class UserRNG extends RNGInitAdapter {
         return nSeeds;
     }
 
+    @Override
+    public void setISeed(int[] seeds) {
+        // TODO: userRNG seems to be not using iseed?
+    }
+
 }
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 3043028d705efe1ff3e2eb9914fb6aae55dbbea2..411da557d81edc47a44d8cbd349fda7e8e3d329f 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
@@ -15805,6 +15805,10 @@ Error in print(x, y) :
 #deparse(c(T, F))
 [1] "c(TRUE, FALSE)"
 
+##com.oracle.truffle.r.test.builtins.TestBuiltin_deparse.testDeparse#
+#deparse(quote(1/0))
+[1] "1/0"
+
 ##com.oracle.truffle.r.test.builtins.TestBuiltin_deparse.testDeparse#
 #deparse(quote(cat(-0)))
 [1] "cat(-0)"
@@ -16478,7 +16482,7 @@ Warning message:
 ‘graphics’ namespace cannot be unloaded:
   namespace ‘graphics’ is imported by ‘stats’ so cannot be unloaded
 
-##com.oracle.truffle.r.test.builtins.TestBuiltin_dfltWarn.testdfltWarn6#Output.IgnoreWarningContext#
+##com.oracle.truffle.r.test.builtins.TestBuiltin_dfltWarn.testdfltWarn6#
 #argv <- list('NaNs produced', quote(log(ifelse(y == 0, 1, y/mu)))); .Internal(.dfltWarn(argv[[1]], argv[[2]]))
 NULL
 Warning message:
@@ -111074,16 +111078,6 @@ Error: 'x' is NULL
 Warning message:
 In qgamma(10, 1) : NaNs produced
 
-##com.oracle.truffle.r.test.library.stats.TestExternal_rbeta.testRbeta#
-#set.seed(42); rbeta(10, 10, 10)
- [1] 0.4282247 0.5459560 0.5805863 0.5512005 0.4866080 0.6987626 0.4880555
- [8] 0.7691043 0.4920874 0.6702352
-
-##com.oracle.truffle.r.test.library.stats.TestExternal_rbeta.testRbeta#
-#set.seed(42); rbeta(10, c(0.1, 2:10), c(0.1, 0.5, 0.9, 3:5))
- [1] 0.002930982 0.969019187 0.872817723 0.593769928 0.260911852 0.561458988
- [7] 1.000000000 0.929063923 0.991793861 0.914489454
-
 ##com.oracle.truffle.r.test.library.stats.TestExternal_rbinom.testRbinom#
 #set.seed(42); rbinom('10', 10, 0.5)
  [1] 7 7 4 7 6 5 6 3 6 6
@@ -111110,62 +111104,21 @@ 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_rcauchy.testRcauchy#
-#set.seed(42); rcauchy(10, 10, -1)
- [1] NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN
-Warning message:
-In rcauchy(10, 10, -1) : NAs produced
-
-##com.oracle.truffle.r.test.library.stats.TestExternal_rcauchy.testRcauchy#
-#set.seed(42); rcauchy(10, 10, 10)
- [1]    7.2577591    7.9970061   22.5740275    4.1049817  -10.9520771
- [6] -156.4897232   -0.8802923   14.5025696   -8.6041975   -3.3131055
-
-##com.oracle.truffle.r.test.library.stats.TestExternal_rcauchy.testRcauchy#
-#set.seed(42); rcauchy(10, NaN, 10)
- [1] NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN
+##com.oracle.truffle.r.test.library.stats.TestExternal_rnbinom.testRbinomWithMu#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))
+  [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
+ [37] NaN NaN NaN NaN NaN NaN NaN   0 NaN NaN NaN NaN NaN NaN NaN NaN   2 NaN
+ [55] NaN NaN NaN NaN NaN NaN NaN   0 NaN NaN NaN  13 NaN NaN NaN NaN NaN NaN
+ [73] NaN NaN  14  30 NaN NaN NaN NaN NaN NaN NaN   0   0   8 NaN NaN NaN NaN
+ [91] NaN NaN   3   1   2 NaN NaN NaN NaN NaN
 Warning message:
-In rcauchy(10, NaN, 10) : NAs produced
+In rnbinom(100, c(-1, 0, 1, 0.8, 10, NA, NaN, 1/0, -1/0), mu = c(-1,  :
+  NAs produced
 
-##com.oracle.truffle.r.test.library.stats.TestExternal_rnorm.testRnorm#
-#set.seed(42); rnorm('10', 10, 5)
- [1] 16.854792  7.176509 11.815642 13.164313 12.021342  9.469377 17.557610
- [8]  9.526705 20.092119  9.686430
-
-##com.oracle.truffle.r.test.library.stats.TestExternal_rnorm.testRnorm#Output.IgnoreWarningContext#
-#set.seed(42); rnorm('aa', 10, 0.5)
-Error in rnorm("aa", 10, 0.5) : invalid arguments
-In addition: Warning message:
-In rnorm("aa", 10, 0.5) : NAs introduced by coercion
-
-##com.oracle.truffle.r.test.library.stats.TestExternal_rnorm.testRnorm#
-#set.seed(42); rnorm(10, 10, 10)
- [1] 23.709584  4.353018 13.631284 16.328626 14.042683  8.938755 25.115220
- [8]  9.053410 30.184237  9.372859
-
-##com.oracle.truffle.r.test.library.stats.TestExternal_rnorm.testRnorm#
-#set.seed(42); rnorm(10, 2:10, c(0.1, 0.5, 0.9))
- [1]  2.137096  2.717651  4.326816  5.063286  6.202134  6.904488  8.151152
- [8]  8.952670 11.816581  1.993729
-
-##com.oracle.truffle.r.test.library.stats.TestExternal_rnorm.testRnorm#
-#set.seed(42); rnorm(1:10, 2:10, c(0.1, 0.5, 0.9))
- [1]  2.137096  2.717651  4.326816  5.063286  6.202134  6.904488  8.151152
- [8]  8.952670 11.816581  1.993729
-
-##com.oracle.truffle.r.test.library.stats.TestExternal_rnorm.testRnorm#
-#set.seed(42); rnorm(c(1,2), 11:12, c(0.1, 0.5, 0.9))
-[1] 11.13710 11.71765
-
-##com.oracle.truffle.r.test.library.stats.TestExternal_runif.testRunif#
-#set.seed(1); runif(5);
-[1] 0.2655087 0.3721239 0.5728534 0.9082078 0.2016819
-
-##com.oracle.truffle.r.test.library.stats.TestExternal_runif.testRunif#
-#set.seed(1); runif(5, 10, 2.5);
-[1] NaN NaN NaN NaN NaN
-Warning message:
-In runif(5, 10, 2.5) : NAs produced
+##com.oracle.truffle.r.test.library.stats.TestExternal_rnbinom.testRbinomWithMu#
+#set.seed(42); rnbinom(5, 1, mu=2)
+[1] 3 3 3 3 4
 
 ##com.oracle.truffle.r.test.library.stats.TestFitting.testLm#Output.IgnoreWhitespace#
 #y <- c(26.55, 37.21, 57.28, 90.82, 20.16, 89.838, 94.46, 20.5, 17.6, 68.7, 38.41, 76.9, 49.7, 71, 99.19, 16); x <- c(26.55, 37.21, 57.28, 90.82, 20.16, 89.838, 94.46, 20.5, 17.6, 68.7, 38.41, 76.9, 49.7, 71, 99.19, 16); res <- lm(y~x); print(res$coefficients);print(res$fitted.values);print(res$xlevels);print(res$residuals);print(res$assign);print(res$effects);print(res$qr$qr);print(res$rank);print(res$model);
@@ -113519,6 +113472,488 @@ $variables
 list(y, z)
 
 
+##com.oracle.truffle.r.test.library.stats.TestRandGenerationFunctions.testFunctions1#Output.IgnoreWhitespace#
+#set.seed(10); rsignrank(12, c(NA, NaN, 1/0, -1/0, -1, 1, 0.3, -0.6, 0.0653, 0.000123, 32e-80, 10))
+ [1] NA NA  0 NA NA  1  0 NA  0  0  0 21
+Warning message:
+In rsignrank(12, c(NA, NaN, 1/0, -1/0, -1, 1, 0.3, -0.6, 0.0653,  :
+  NAs produced
+
+##com.oracle.truffle.r.test.library.stats.TestRandGenerationFunctions.testFunctions1#Output.IgnoreWhitespace#
+#set.seed(2); rchisq(13, c(NA, NaN, 1/0, -1/0, -1, 1, 0.3, -0.5, 0.0653, 0.000123, 32e-80, 8833, 79e70))
+ [1]          NaN          NaN          NaN          NaN          NaN
+ [6] 9.582518e-02 7.012801e-02          NaN 2.294588e-10 0.000000e+00
+[11] 0.000000e+00 8.813564e+03 7.900000e+71
+Warning message:
+In rchisq(13, c(NA, NaN, 1/0, -1/0, -1, 1, 0.3, -0.5, 0.0653, 0.000123,  :
+  NAs produced
+
+##com.oracle.truffle.r.test.library.stats.TestRandGenerationFunctions.testFunctions1#Output.IgnoreWhitespace#
+#set.seed(2); rexp(13, c(NA, NaN, 1/0, -1/0, -1, 1, 0.3, -0.5, 0.0653, 0.000123, 32e-80, 8833, 79e70))
+ [1]          NaN          NaN 0.000000e+00 0.000000e+00          NaN
+ [6] 1.865352e+00 1.349160e+00          NaN 2.245830e+00 1.407081e+04
+[11] 2.797693e+77 7.550069e-05 1.359958e-72
+Warning message:
+In rexp(13, c(NA, NaN, 1/0, -1/0, -1, 1, 0.3, -0.5, 0.0653, 0.000123,  :
+  NAs produced
+
+##com.oracle.truffle.r.test.library.stats.TestRandGenerationFunctions.testFunctions1#Output.IgnoreWhitespace#
+#set.seed(2); rgeom(13, c(NA, NaN, 1/0, -1/0, -1, 1, 0.3, -0.5, 0.0653, 0.000123, 32e-80, 8833, 79e70))
+ [1]    NA    NA    NA    NA    NA     0     1    NA    32 11643    NA    NA
+[13]    NA
+Warning message:
+In rgeom(13, c(NA, NaN, 1/0, -1/0, -1, 1, 0.3, -0.5, 0.0653, 0.000123,  :
+  NAs produced
+
+##com.oracle.truffle.r.test.library.stats.TestRandGenerationFunctions.testFunctions1#Output.IgnoreWhitespace#
+#set.seed(2); rpois(13, c(NA, NaN, 1/0, -1/0, -1, 1, 0.3, -0.5, 0.0653, 0.000123, 32e-80, 8833, 79e70))
+ [1]   NA   NA   NA   NA   NA    0    0   NA    0    0    0 8981   NA
+Warning message:
+In rpois(13, c(NA, NaN, 1/0, -1/0, -1, 1, 0.3, -0.5, 0.0653, 0.000123,  :
+  NAs produced
+
+##com.oracle.truffle.r.test.library.stats.TestRandGenerationFunctions.testFunctions1#Output.IgnoreWhitespace#
+#set.seed(2); rt(13, c(NA, NaN, 1/0, -1/0, -1, 1, 0.3, -0.5, 0.0653, 0.000123, 32e-80, 8833, 79e70))
+ [1]         NaN         NaN -0.89691455         NaN         NaN  0.19975785
+ [7] -0.06927937         NaN  0.96073767        -Inf         Inf  0.87841766
+[13]  1.01282869
+Warning message:
+In rt(13, c(NA, NaN, 1/0, -1/0, -1, 1, 0.3, -0.5, 0.0653, 0.000123,  :
+  NAs produced
+
+##com.oracle.truffle.r.test.library.stats.TestRandGenerationFunctions.testFunctions2#Output.IgnoreWhitespace#
+#set.seed(1); rbeta(10, 10, 10)
+ [1] 0.4202441 0.5231868 0.3929161 0.7104015 0.5416782 0.3949132 0.5618393
+ [8] 0.5943116 0.5732049 0.4613867
+
+##com.oracle.truffle.r.test.library.stats.TestRandGenerationFunctions.testFunctions2#Output.IgnoreWhitespace#
+#set.seed(1); rbeta(20, c(-1, 0, 0.2, 2:5), c(-1, 0, 0.1, 0.9, 3))
+ [1]        NaN 0.00000000 1.00000000 0.82338531 0.17213601        NaN
+ [7] 1.00000000        NaN 0.00000000 0.06525112        NaN 1.00000000
+[13] 0.99955874 0.92371833        NaN        NaN 1.00000000 0.99409008
+[19] 0.93534230 0.58348863
+Warning message:
+In rbeta(20, c(-1, 0, 0.2, 2:5), c(-1, 0, 0.1, 0.9, 3)) : NAs produced
+
+##com.oracle.truffle.r.test.library.stats.TestRandGenerationFunctions.testFunctions2#Output.IgnoreWhitespace#
+#set.seed(1); rbeta(24, c(0.0653, 0.000123, 32e-80, 8833, 79e70), c(0.0653, 0.000123, 32e-80, 8833, 79e70, 0, -1))
+ [1]  9.999998e-01 6.842102e-313  1.000000e+00  5.020914e-01  5.000000e-01
+ [6]  1.000000e+00           NaN  0.000000e+00  1.000000e+00  1.000000e+00
+[11]  2.914034e-12 6.842102e-313  1.000000e+00           NaN  1.000000e+00
+[16]  1.000000e+00  1.000000e+00  0.000000e+00  1.117379e-68  1.000000e+00
+[21]           NaN 6.842102e-313  0.000000e+00  1.000000e+00
+Warning message:
+In rbeta(24, c(0.0653, 0.000123, 3.2e-79, 8833, 7.9e+71), c(0.0653,  :
+  NAs produced
+
+##com.oracle.truffle.r.test.library.stats.TestRandGenerationFunctions.testFunctions2#Output.IgnoreWhitespace#
+#set.seed(1); rbeta(30, c(NA, 0, NaN, 1/0, -1/0), c(NaN, NaN, NA, 0, 1/0, -1/0))
+ [1] NaN NaN NaN 1.0 NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN 0.0 NaN NaN
+[20] NaN NaN 0.0 NaN NaN NaN NaN NaN NaN 0.5 NaN
+Warning message:
+In rbeta(30, c(NA, 0, NaN, 1/0, -1/0), c(NaN, NaN, NA, 0, 1/0, -1/0)) :
+  NAs produced
+
+##com.oracle.truffle.r.test.library.stats.TestRandGenerationFunctions.testFunctions2#Output.IgnoreWhitespace#
+#set.seed(1); rcauchy(10, 10, 10)
+ [1]  21.025199  33.538306 -32.926262   7.033574  17.346469   6.694780
+ [7]   8.244206  -8.082431 -13.286244  11.965824
+
+##com.oracle.truffle.r.test.library.stats.TestRandGenerationFunctions.testFunctions2#Output.IgnoreWhitespace#
+#set.seed(1); rcauchy(20, c(-1, 0, 0.2, 2:5), c(-1, 0, 0.1, 0.9, 3))
+ [1]        NaN  0.0000000  0.3102520  4.1184475 -9.8778787        NaN
+ [7]  5.0000000 -1.0296643  0.6611822 -0.7915660        NaN  3.0000000
+[13]  3.9824421  3.3725812 -7.9858732        NaN  0.2000000  2.0196582
+[19]  3.6800580  5.8586450
+Warning message:
+In rcauchy(20, c(-1, 0, 0.2, 2:5), c(-1, 0, 0.1, 0.9, 3)) : NAs produced
+
+##com.oracle.truffle.r.test.library.stats.TestRandGenerationFunctions.testFunctions2#Output.IgnoreWhitespace#
+#set.seed(1); rcauchy(24, c(0.0653, 0.000123, 32e-80, 8833, 79e70), c(0.0653, 0.000123, 32e-80, 8833, 79e70, 0, -1))
+ [1]  1.372945e-01  4.125212e-04 -1.053640e-78  6.212756e+03  1.370371e+72
+ [6]  6.530000e-02           NaN -2.158309e-02  8.833000e+03  7.900000e+71
+[11] -2.056867e+04  1.553001e+71  3.200000e-79           NaN  7.900000e+71
+[16]  6.537620e-02  1.230000e-04  2.317827e+04 -6.971785e+71  7.900000e+71
+[21]           NaN  9.034221e+00 -1.509671e-04  8.833000e+03
+Warning message:
+In rcauchy(24, c(0.0653, 0.000123, 3.2e-79, 8833, 7.9e+71), c(0.0653,  :
+  NAs produced
+
+##com.oracle.truffle.r.test.library.stats.TestRandGenerationFunctions.testFunctions2#Output.IgnoreWhitespace#
+#set.seed(1); rcauchy(30, c(NA, 0, NaN, 1/0, -1/0), c(NaN, NaN, NA, 0, 1/0, -1/0))
+ [1]  NaN  NaN  NaN  Inf  NaN  NaN  NaN  NaN  NaN -Inf  NaN  NaN  NaN  NaN  NaN
+[16]  NaN  NaN  NaN  NaN  NaN  NaN    0  NaN  NaN  NaN  NaN  NaN  NaN  NaN  NaN
+Warning message:
+In rcauchy(30, c(NA, 0, NaN, 1/0, -1/0), c(NaN, NaN, NA, 0, 1/0,  :
+  NAs produced
+
+##com.oracle.truffle.r.test.library.stats.TestRandGenerationFunctions.testFunctions2#Output.IgnoreWhitespace#
+#set.seed(1); rchisq(10, 10, 10)
+ [1] 11.63643 18.45545 21.64372 16.07794 20.36424 15.71556 20.77667 26.42402
+ [9] 20.58523 10.62996
+
+##com.oracle.truffle.r.test.library.stats.TestRandGenerationFunctions.testFunctions2#Output.IgnoreWhitespace#
+#set.seed(1); rchisq(20, c(-1, 0, 0.2, 2:5), c(-1, 0, 0.1, 0.9, 3))
+ [1]          NaN 0.000000e+00 1.461521e-04 1.839736e+00 6.956474e-01
+ [6]          NaN 3.209835e+00          NaN 7.291872e+00 7.885483e+00
+[11]          NaN 9.504888e-01 6.388242e+00 4.745204e+00          NaN
+[16]          NaN 1.439251e-07 2.498584e+00 4.578127e+00 5.322404e+00
+Warning message:
+In rchisq(20, c(-1, 0, 0.2, 2:5), c(-1, 0, 0.1, 0.9, 3)) : NAs produced
+
+##com.oracle.truffle.r.test.library.stats.TestRandGenerationFunctions.testFunctions2#Output.IgnoreWhitespace#
+#set.seed(1); rchisq(24, c(0.0653, 0.000123, 32e-80, 8833, 79e70), c(0.0653, 0.000123, 32e-80, 8833, 79e70, 0, -1))
+ [1] 2.046068e-13 0.000000e+00 0.000000e+00 1.771339e+04 1.580000e+72
+ [6] 8.055558e-18          NaN 0.000000e+00 8.829848e+03 7.900000e+71
+[11] 9.032093e+03 7.900000e+71 0.000000e+00          NaN 7.900000e+71
+[16] 1.767431e-01 0.000000e+00 8.563832e+03 7.900000e+71 7.900000e+71
+[21]          NaN 0.000000e+00 0.000000e+00 8.986379e+03
+Warning message:
+In rchisq(24, c(0.0653, 0.000123, 3.2e-79, 8833, 7.9e+71), c(0.0653,  :
+  NAs produced
+
+##com.oracle.truffle.r.test.library.stats.TestRandGenerationFunctions.testFunctions2#Output.IgnoreWhitespace#
+#set.seed(1); rchisq(30, c(NA, 0, NaN, 1/0, -1/0), c(NaN, NaN, NA, 0, 1/0, -1/0))
+ [1] NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN
+[20] NaN NaN   0 NaN NaN NaN NaN NaN NaN NaN NaN
+Warning message:
+In rchisq(30, c(NA, 0, NaN, 1/0, -1/0), c(NaN, NaN, NA, 0, 1/0,  :
+  NAs produced
+
+##com.oracle.truffle.r.test.library.stats.TestRandGenerationFunctions.testFunctions2#Output.IgnoreWhitespace#
+#set.seed(1); rf(10, 10, 10)
+ [1] 0.4211249 1.4022872 0.3264808 1.0686054 1.3072335 0.8433459 1.5694522
+ [8] 1.0962100 1.0552082 3.6708927
+
+##com.oracle.truffle.r.test.library.stats.TestRandGenerationFunctions.testFunctions2#Output.IgnoreWhitespace#
+#set.seed(1); rf(20, c(-1, 0, 0.2, 2:5), c(-1, 0, 0.1, 0.9, 3))
+ [1]          NaN          NaN 5.990604e-02 2.030321e+00 4.383017e-01
+ [6]          NaN          NaN          NaN          NaN 4.387668e-04
+[11]          NaN          NaN 1.015302e+10 1.322782e-01          NaN
+[16]          NaN          NaN 2.373490e-01 1.865997e+00 1.215399e+00
+Warning message:
+In rf(20, c(-1, 0, 0.2, 2:5), c(-1, 0, 0.1, 0.9, 3)) : NAs produced
+
+##com.oracle.truffle.r.test.library.stats.TestRandGenerationFunctions.testFunctions2#Output.IgnoreWhitespace#
+#set.seed(1); rf(24, c(0.0653, 0.000123, 32e-80, 8833, 79e70), c(0.0653, 0.000123, 32e-80, 8833, 79e70, 0, -1))
+ [1] 5.907040e-11          NaN          NaN 1.024705e+00 1.000000e+00
+ [6]          NaN          NaN 0.000000e+00          Inf          Inf
+[11] 1.607677e-07 0.000000e+00          NaN          NaN 2.079267e+10
+[16]          Inf          NaN 0.000000e+00 9.974128e-01          NaN
+[21]          NaN 0.000000e+00          NaN          Inf
+Warning message:
+In rf(24, c(0.0653, 0.000123, 3.2e-79, 8833, 7.9e+71), c(0.0653,  :
+  NAs produced
+
+##com.oracle.truffle.r.test.library.stats.TestRandGenerationFunctions.testFunctions2#Output.IgnoreWhitespace#
+#set.seed(1); rf(30, c(NA, 0, NaN, 1/0, -1/0), c(NaN, NaN, NA, 0, 1/0, -1/0))
+ [1] NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN
+[20] NaN NaN NaN NaN NaN NaN NaN NaN NaN   1 NaN
+Warning message:
+In rf(30, c(NA, 0, NaN, 1/0, -1/0), c(NaN, NaN, NA, 0, 1/0, -1/0)) :
+  NAs produced
+
+##com.oracle.truffle.r.test.library.stats.TestRandGenerationFunctions.testFunctions2#Output.IgnoreWhitespace#
+#set.seed(1); rgamma(10, 10, 10)
+ [1] 0.7667251 1.4040808 1.3826660 1.0820993 0.5346417 1.1061754 1.1911950
+ [8] 1.1357558 0.8582045 0.7196892
+
+##com.oracle.truffle.r.test.library.stats.TestRandGenerationFunctions.testFunctions2#Output.IgnoreWhitespace#
+#set.seed(1); rgamma(20, c(-1, 0, 0.2, 2:5), c(-1, 0, 0.1, 0.9, 3))
+ [1]         NaN  0.00000000  0.01881730  1.92594160  0.45110798         NaN
+ [7]         Inf         NaN  0.00000000  0.05989429         NaN         Inf
+[13] 62.08824595  6.89167118         NaN  0.00000000         Inf 22.88066299
+[19]  2.26717120  0.72159817
+Warning message:
+In rgamma(20, c(-1, 0, 0.2, 2:5), c(-1, 0, 0.1, 0.9, 3)) : NAs produced
+
+##com.oracle.truffle.r.test.library.stats.TestRandGenerationFunctions.testFunctions2#Output.IgnoreWhitespace#
+#set.seed(1); rgamma(24, c(0.0653, 0.000123, 32e-80, 8833, 79e70), c(0.0653, 0.000123, 32e-80, 8833, 79e70, 0, -1))
+ [1]  3.336908e-08  0.000000e+00  0.000000e+00  1.003452e+00  1.000000e+00
+ [6]           Inf           NaN  0.000000e+00  7.180454e+07 2.468750e+150
+[11]  7.939465e-15  0.000000e+00           Inf           NaN  1.209801e+73
+[16]  1.378517e+03  0.000000e+00  0.000000e+00  1.129294e-68           Inf
+[21]           NaN  0.000000e+00  0.000000e+00  2.783175e+82
+Warning message:
+In rgamma(24, c(0.0653, 0.000123, 3.2e-79, 8833, 7.9e+71), c(0.0653,  :
+  NAs produced
+
+##com.oracle.truffle.r.test.library.stats.TestRandGenerationFunctions.testFunctions2#Output.IgnoreWhitespace#
+#set.seed(1); rgamma(30, c(NA, 0, NaN, 1/0, -1/0), c(NaN, NaN, NA, 0, 1/0, -1/0))
+ [1] NaN NaN NaN Inf   0 NaN NaN NaN NaN NaN NaN   0 NaN NaN NaN NaN   0 NaN NaN
+[20] NaN NaN   0 NaN   0 NaN NaN NaN NaN   0   0
+Warning message:
+In rgamma(30, c(NA, 0, NaN, 1/0, -1/0), c(NaN, NaN, NA, 0, 1/0,  :
+  NAs produced
+
+##com.oracle.truffle.r.test.library.stats.TestRandGenerationFunctions.testFunctions2#Output.IgnoreWhitespace#
+#set.seed(1); rlogis(10, 10, 10)
+ [1]  -0.1753073   4.7688401  12.9350241  32.9194576  -3.7581524  31.7945887
+ [7]  38.3762121  16.6685147  15.2841793 -17.2029660
+
+##com.oracle.truffle.r.test.library.stats.TestRandGenerationFunctions.testFunctions2#Output.IgnoreWhitespace#
+#set.seed(1); rlogis(20, c(-1, 0, 0.2, 2:5), c(-1, 0, 0.1, 0.9, 3))
+ [1]  0.01753073  0.00000000  0.14768840  2.26415217  9.87583728  5.37581524
+ [7]  5.00000000 -0.78205411  2.55385909  2.20055441  1.47158207  3.00000000
+[13]  3.72797034  3.78557353 -5.61955679 -0.78623735  0.20000000  1.95278340
+[19]  4.08667440  3.97239071
+
+##com.oracle.truffle.r.test.library.stats.TestRandGenerationFunctions.testFunctions2#Output.IgnoreWhitespace#
+#set.seed(1); rlogis(24, c(0.0653, 0.000123, 32e-80, 8833, 79e70), c(0.0653, 0.000123, 32e-80, 8833, 79e70, 0, -1))
+ [1] -1.144757e-03  5.865673e-05  4.139208e-79  2.907776e+04 -2.968940e+71
+ [6]  6.530000e-02 -2.179336e+00  1.852967e-01  8.833000e+03  7.900000e+71
+[11] -2.402831e+04 -1.065997e+72  3.200000e-79  8.834540e+03  7.900000e+71
+[16]  6.524192e-02  1.230000e-04 -8.129095e+01  7.368165e+71  7.900000e+71
+[21] -4.743217e+00 -3.183475e-02  1.538533e-04  8.833000e+03
+
+##com.oracle.truffle.r.test.library.stats.TestRandGenerationFunctions.testFunctions2#Output.IgnoreWhitespace#
+#set.seed(1); rlogis(30, c(NA, 0, NaN, 1/0, -1/0), c(NaN, NaN, NA, 0, 1/0, -1/0))
+ [1]  NaN  NaN  NaN  Inf  NaN  NaN  NaN  NaN  NaN -Inf  NaN  NaN  NaN  NaN  NaN
+[16]  NaN  NaN  NaN  NaN  NaN  NaN    0  NaN  NaN  NaN  NaN  NaN  NaN  NaN  NaN
+Warning message:
+In rlogis(30, c(NA, 0, NaN, 1/0, -1/0), c(NaN, NaN, NA, 0, 1/0,  :
+  NAs produced
+
+##com.oracle.truffle.r.test.library.stats.TestRandGenerationFunctions.testFunctions2#Output.IgnoreWhitespace#
+#set.seed(1); rnorm(10, 10, 10)
+ [1]  3.735462 11.836433  1.643714 25.952808 13.295078  1.795316 14.874291
+ [8] 17.383247 15.757814  6.946116
+
+##com.oracle.truffle.r.test.library.stats.TestRandGenerationFunctions.testFunctions2#Output.IgnoreWhitespace#
+#set.seed(1); rnorm(20, c(-1, 0, 0.2, 2:5), c(-1, 0, 0.1, 0.9, 3))
+ [1]        NaN  0.0000000  0.1373546  2.1652790  0.4931142        NaN
+ [7]  5.0000000 -0.8404719  0.2965570 -2.2614052        NaN  3.0000000
+[13]  4.0487429  5.6644922  0.7273441        NaN  0.2000000  1.9694612
+[19]  4.3606031  5.1695297
+Warning message:
+In rnorm(20, c(-1, 0, 0.2, 2:5), c(-1, 0, 0.1, 0.9, 3)) : NAs produced
+
+##com.oracle.truffle.r.test.library.stats.TestRandGenerationFunctions.testFunctions2#Output.IgnoreWhitespace#
+#set.seed(1); rnorm(24, c(0.0653, 0.000123, 32e-80, 8833, 79e70), c(0.0653, 0.000123, 32e-80, 8833, 79e70, 0, -1))
+ [1]  2.439257e-02  1.455881e-04  5.259884e-80  2.292412e+04  1.050311e+72
+ [6]  6.530000e-02           NaN -5.357659e-02  8.833000e+03  7.900000e+71
+[11]  5.085942e+03 -2.412568e+71  3.200000e-79           NaN  7.900000e+71
+[16]  6.534795e-02  1.230000e-04 -1.956244e+04  8.886954e+71  7.900000e+71
+[21]           NaN -2.811165e-03 -1.991402e-06  8.833000e+03
+Warning message:
+In rnorm(24, c(0.0653, 0.000123, 3.2e-79, 8833, 7.9e+71), c(0.0653,  :
+  NAs produced
+
+##com.oracle.truffle.r.test.library.stats.TestRandGenerationFunctions.testFunctions2#Output.IgnoreWhitespace#
+#set.seed(1); rnorm(30, c(NA, 0, NaN, 1/0, -1/0), c(NaN, NaN, NA, 0, 1/0, -1/0))
+ [1]  NaN  NaN  NaN  Inf  NaN  NaN  NaN  NaN  NaN -Inf  NaN  NaN  NaN  NaN  NaN
+[16]  NaN  NaN  NaN  NaN  NaN  NaN    0  NaN  NaN  NaN  NaN  NaN  NaN  NaN  NaN
+Warning message:
+In rnorm(30, c(NA, 0, NaN, 1/0, -1/0), c(NaN, NaN, NA, 0, 1/0, -1/0)) :
+  NAs produced
+
+##com.oracle.truffle.r.test.library.stats.TestRandGenerationFunctions.testFunctions2#Output.IgnoreWhitespace#
+#set.seed(1); runif(10, 10, 10)
+ [1] 10 10 10 10 10 10 10 10 10 10
+
+##com.oracle.truffle.r.test.library.stats.TestRandGenerationFunctions.testFunctions2#Output.IgnoreWhitespace#
+#set.seed(1); runif(20, c(-1, 0, 0.2, 2:5), c(-1, 0, 0.1, 0.9, 3))
+ [1] -1.0000000  0.0000000        NaN        NaN  3.0000000        NaN
+ [7]        NaN -0.7079405  0.3349115  1.8039894        NaN        NaN
+[13]        NaN        NaN  2.6328312        NaN        NaN        NaN
+[19]        NaN        NaN
+Warning message:
+In runif(20, c(-1, 0, 0.2, 2:5), c(-1, 0, 0.1, 0.9, 3)) : NAs produced
+
+##com.oracle.truffle.r.test.library.stats.TestRandGenerationFunctions.testFunctions2#Output.IgnoreWhitespace#
+#set.seed(1); runif(24, c(0.0653, 0.000123, 32e-80, 8833, 79e70), c(0.0653, 0.000123, 32e-80, 8833, 79e70, 0, -1))
+ [1] 6.530000e-02 1.230000e-04 3.200000e-79 8.833000e+03 7.900000e+71
+ [6]          NaN          NaN 1.733772e-02          NaN          NaN
+[11] 3.287011e+03 4.525542e+71          NaN          NaN          NaN
+[16]          NaN          NaN 8.022199e+03 1.593287e+71          NaN
+[21]          NaN 5.867734e-02 1.161951e-04          NaN
+Warning message:
+In runif(24, c(0.0653, 0.000123, 3.2e-79, 8833, 7.9e+71), c(0.0653,  :
+  NAs produced
+
+##com.oracle.truffle.r.test.library.stats.TestRandGenerationFunctions.testFunctions2#Output.IgnoreWhitespace#
+#set.seed(1); runif(30, c(NA, 0, NaN, 1/0, -1/0), c(NaN, NaN, NA, 0, 1/0, -1/0))
+ [1] NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN
+[20] NaN NaN   0 NaN NaN NaN NaN NaN NaN NaN NaN
+Warning message:
+In runif(30, c(NA, 0, NaN, 1/0, -1/0), c(NaN, NaN, NA, 0, 1/0, -1/0)) :
+  NAs produced
+
+##com.oracle.truffle.r.test.library.stats.TestRandGenerationFunctions.testFunctions2#Output.IgnoreWhitespace#
+#set.seed(1); rweibull(10, 10, 10)
+ [1] 10.286269  9.988469  9.431816  7.913244 10.481920  7.998338  7.507960
+ [8]  9.156558  9.259757 11.078171
+
+##com.oracle.truffle.r.test.library.stats.TestRandGenerationFunctions.testFunctions2#Output.IgnoreWhitespace#
+#set.seed(1); rweibull(20, c(-1, 0, 0.2, 2:5), c(-1, 0, 0.1, 0.9, 3))
+ [1]          NaN 0.000000e+00 4.101041e-01 8.948229e-01 2.468533e+00
+ [6]          NaN 0.000000e+00          NaN          NaN 2.482268e-05
+[11]          NaN 0.000000e+00 1.124869e-01 5.757607e-01          NaN
+[16]          NaN 0.000000e+00 2.385666e-02 6.709396e-01 2.475257e+00
+Warning message:
+In rweibull(20, c(-1, 0, 0.2, 2:5), c(-1, 0, 0.1, 0.9, 3)) : NAs produced
+
+##com.oracle.truffle.r.test.library.stats.TestRandGenerationFunctions.testFunctions2#Output.IgnoreWhitespace#
+#set.seed(1); rweibull(24, c(0.0653, 0.000123, 32e-80, 8833, 79e70), c(0.0653, 0.000123, 32e-80, 8833, 79e70, 0, -1))
+ [1] 4.921274e+00 2.245712e-45 0.000000e+00 8.830660e+03 7.900000e+71
+ [6] 0.000000e+00          NaN 0.000000e+00 1.229601e-04 3.200000e-79
+[11] 6.779436e-02          Inf 0.000000e+00          NaN 6.530000e-02
+[16] 5.637942e-01 0.000000e+00 0.000000e+00 7.898801e+71 0.000000e+00
+[21]          NaN 0.000000e+00 0.000000e+00 3.198257e-79
+Warning message:
+In rweibull(24, c(0.0653, 0.000123, 3.2e-79, 8833, 7.9e+71), c(0.0653,  :
+  NAs produced
+
+##com.oracle.truffle.r.test.library.stats.TestRandGenerationFunctions.testFunctions2#Output.IgnoreWhitespace#
+#set.seed(1); rweibull(30, c(NA, 0, NaN, 1/0, -1/0), c(NaN, NaN, NA, 0, 1/0, -1/0))
+ [1] NaN NaN NaN   0 NaN NaN NaN NaN NaN   0 NaN NaN NaN NaN NaN   0 NaN NaN NaN
+[20] NaN NaN   0 NaN NaN NaN NaN NaN   0 NaN NaN
+Warning message:
+In rweibull(30, c(NA, 0, NaN, 1/0, -1/0), c(NaN, NaN, NA, 0, 1/0,  :
+  NAs produced
+
+##com.oracle.truffle.r.test.library.stats.TestRandGenerationFunctions.testFunctions2#Output.IgnoreWhitespace#
+#set.seed(1); rwilcox(10, 10, 10)
+ [1] 48 56 42 49 53 61 46 67 30 47
+
+##com.oracle.truffle.r.test.library.stats.TestRandGenerationFunctions.testFunctions2#Output.IgnoreWhitespace#
+#set.seed(1); rwilcox(20, c(-1, 0, 0.2, 2:5), c(-1, 0, 0.1, 0.9, 3))
+ [1] NA  0  0  0  7 NA  0 NA  0  0 NA  0  0  1 NA NA  0  0  3 11
+Warning message:
+In rwilcox(20, c(-1, 0, 0.2, 2:5), c(-1, 0, 0.1, 0.9, 3)) : NAs produced
+
+##com.oracle.truffle.r.test.library.stats.TestRandGenerationFunctions.testFunctions2#Output.IgnoreWhitespace#
+#set.seed(1); rwilcox(24, c(0.0653, 0.000123, 32e-80, 8833, 79e70), c(0.0653, 0.000123, 32e-80, 8833, 79e70, 0, -1))
+Error in rwilcox(24, c(0.0653, 0.000123, 3.2e-79, 8833, 7.9e+71), c(0.0653,  :
+  'Calloc' could not allocate memory (18446744071562067968 of 4 bytes)
+
+##com.oracle.truffle.r.test.library.stats.TestRandGenerationFunctions.testFunctions2#Output.IgnoreWhitespace#
+#set.seed(1); rwilcox(30, c(NA, 0, NaN, 1/0, -1/0), c(NaN, NaN, NA, 0, 1/0, -1/0))
+Error in rwilcox(30, c(NA, 0, NaN, 1/0, -1/0), c(NaN, NaN, NA, 0, 1/0,  :
+  'Calloc' could not allocate memory (18446744071562067968 of 4 bytes)
+
+##com.oracle.truffle.r.test.library.stats.TestRandGenerationFunctions.testFunctions2Infrastructure#
+#length(runif('3'))
+[1] 3
+
+##com.oracle.truffle.r.test.library.stats.TestRandGenerationFunctions.testFunctions2Infrastructure#
+#length(runif(c('a', 'b', 'b', 'd')))
+[1] 4
+
+##com.oracle.truffle.r.test.library.stats.TestRandGenerationFunctions.testFunctions2Infrastructure#
+#length(runif(c(1,2,3)))
+[1] 3
+
+##com.oracle.truffle.r.test.library.stats.TestRandGenerationFunctions.testFunctions2Infrastructure#Output.IgnoreWarningContext#
+#runif('hello')
+Error in runif("hello") : invalid arguments
+In addition: Warning message:
+In runif("hello") : NAs introduced by coercion
+
+##com.oracle.truffle.r.test.library.stats.TestRandGenerationFunctions.testFunctions2Infrastructure#
+#runif(-1, 1, 2)
+Error in runif(-1, 1, 2) : invalid arguments
+
+##com.oracle.truffle.r.test.library.stats.TestRandGenerationFunctions.testFunctions2Infrastructure#
+#runif(2, 2, numeric())
+[1] NA NA
+Warning message:
+In runif(2, 2, numeric()) : NAs produced
+
+##com.oracle.truffle.r.test.library.stats.TestRandGenerationFunctions.testFunctions2Infrastructure#
+#runif(2, numeric(), 2)
+[1] NA NA
+Warning message:
+In runif(2, numeric(), 2) : NAs produced
+
+##com.oracle.truffle.r.test.library.stats.TestRandGenerationFunctions.testFunctions3#
+#rhyper(1, -5, 5, 20)
+[1] NA
+Warning message:
+In rhyper(1, -5, 5, 20) : NAs produced
+
+##com.oracle.truffle.r.test.library.stats.TestRandGenerationFunctions.testFunctions3#
+#rhyper(1, 5, 5, -1/0)
+[1] NA
+Warning message:
+In rhyper(1, 5, 5, -1/0) : NAs produced
+
+##com.oracle.truffle.r.test.library.stats.TestRandGenerationFunctions.testFunctions3#
+#rhyper(1, 5, 5, 1/0)
+[1] NA
+Warning message:
+In rhyper(1, 5, 5, 1/0) : NAs produced
+
+##com.oracle.truffle.r.test.library.stats.TestRandGenerationFunctions.testFunctions3#
+#rhyper(1, 5, 5, 20)
+[1] NA
+Warning message:
+In rhyper(1, 5, 5, 20) : NAs produced
+
+##com.oracle.truffle.r.test.library.stats.TestRandGenerationFunctions.testFunctions3#
+#rhyper(1, 5, NaN, 20)
+[1] NA
+Warning message:
+In rhyper(1, 5, NaN, 20) : NAs produced
+
+##com.oracle.truffle.r.test.library.stats.TestRandGenerationFunctions.testFunctions3#
+#rhyper(1, NA, 5, 20)
+[1] NA
+Warning message:
+In rhyper(1, NA, 5, 20) : NAs produced
+
+##com.oracle.truffle.r.test.library.stats.TestRandGenerationFunctions.testFunctions3#
+#set.seed(3); rhyper(2, 1000, 1000, 5)
+[1] 1 3
+
+##com.oracle.truffle.r.test.library.stats.TestRandGenerationFunctions.testFunctions3#
+#set.seed(3); rhyper(3, 10, 10, 5)
+[1] 2 3 2
+
+##com.oracle.truffle.r.test.library.stats.TestRandGenerationFunctions.testFunctions3#
+#set.seed(3); rhyper(3, 10, 79e70, 2)
+[1] 0 0 0
+
+##com.oracle.truffle.r.test.library.stats.TestRandGenerationFunctions.testRmultinom#Output.IgnoreErrorContext#Output.IgnoreErrorMessage#
+#rmultinom('string', 1, 0.15)
+Error in rmultinom("string", 1, 0.15) : invalid first argument 'n'
+In addition: Warning message:
+In rmultinom("string", 1, 0.15) : NAs introduced by coercion
+
+##com.oracle.truffle.r.test.library.stats.TestRandGenerationFunctions.testRmultinom#
+#rmultinom(1, 1, -0.15)
+Error in rmultinom(1, 1, -0.15) : negative probability
+
+##com.oracle.truffle.r.test.library.stats.TestRandGenerationFunctions.testRmultinom#
+#rmultinom(1, NA, 0.2)
+Error in rmultinom(1, NA, 0.2) : invalid second argument 'size'
+
+##com.oracle.truffle.r.test.library.stats.TestRandGenerationFunctions.testRmultinom#
+#rmultinom(NA, 1, 0.2)
+Error in rmultinom(NA, 1, 0.2) : invalid first argument 'n'
+
+##com.oracle.truffle.r.test.library.stats.TestRandGenerationFunctions.testRmultinom#
+#set.seed(11); rmultinom(10, 5, c(0.1, 0.1, 0.3, 0.2, 0.3))
+     [,1] [,2] [,3] [,4] [,5] [,6] [,7] [,8] [,9] [,10]
+[1,]    0    0    1    1    0    0    0    0    0     0
+[2,]    0    2    0    1    0    1    0    0    0     0
+[3,]    2    0    1    2    1    1    2    2    3     1
+[4,]    0    1    1    0    2    1    0    1    1     0
+[5,]    3    2    2    1    2    2    3    2    1     4
+
+##com.oracle.truffle.r.test.library.stats.TestRandGenerationFunctions.testRmultinom#
+#set.seed(11); rmultinom(7, 8, structure(c(0.1, 0.1), .Names=c('a', 'B')))
+  [,1] [,2] [,3] [,4] [,5] [,6] [,7]
+a    3    0    4    1    2    6    2
+B    5    8    4    7    6    2    6
+
+##com.oracle.truffle.r.test.library.stats.TestRandGenerationFunctions.testRmultinom#
+#set.seed(12); rmultinom('5', 3.1, c(2, 5, 10))
+     [,1] [,2] [,3] [,4] [,5]
+[1,]    0    1    0    0    0
+[2,]    2    0    0    1    0
+[3,]    1    2    3    2    3
+
 ##com.oracle.truffle.r.test.library.stats.TestStats.testCor#
 #{ as.integer(cor(c(1,2,3),c(1,2,5))*10000000) }
 [1] 9607689
@@ -114619,6 +115054,30 @@ see '?methods' for accessing help and source code
 "","double","bool","raw"
 "1",1231231234.5,TRUE,2a
 
+##com.oracle.truffle.r.test.parser.TestParser.testDoubleLiterals#
+#0x0p0
+[1] 0
+
+##com.oracle.truffle.r.test.parser.TestParser.testDoubleLiterals#
+#0x1.1p2
+[1] 4.25
+
+##com.oracle.truffle.r.test.parser.TestParser.testDoubleLiterals#
+#0x1.aP2
+[1] 6.5
+
+##com.oracle.truffle.r.test.parser.TestParser.testDoubleLiterals#
+#0x1p2
+[1] 4
+
+##com.oracle.truffle.r.test.parser.TestParser.testDoubleLiterals#
+#0xa.bp1i
+[1] 0+21.375i
+
+##com.oracle.truffle.r.test.parser.TestParser.testDoubleLiterals#
+#0xa.p2
+[1] 40
+
 ##com.oracle.truffle.r.test.parser.TestParser.testLexerError#Output.IgnoreErrorMessage#
 #%0
 Error: unexpected input in "%0"
diff --git a/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/builtins/TestBuiltin_deparse.java b/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/builtins/TestBuiltin_deparse.java
index 071f3a353962ee7d1205b4a095f5ffb4358ca974..b1d19e945d05d1bb20551aa2f3eb906fe4bd6f31 100644
--- a/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/builtins/TestBuiltin_deparse.java
+++ b/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/builtins/TestBuiltin_deparse.java
@@ -303,6 +303,8 @@ public class TestBuiltin_deparse extends TestBase {
         assertEval("unserialize(serialize(quote(a[a <- TRUE]), NULL))");
 
         assertEval("{ x<-c(a=42, b=7); deparse(x) }");
+
+        assertEval("deparse(quote(1/0))");
     }
 
     @Test
diff --git a/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/builtins/TestBuiltin_dfltWarn.java b/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/builtins/TestBuiltin_dfltWarn.java
index f03a54da486fd77971c41815798d66ad92d11141..1b21fd0bc0cd63e857130ac537af14babad43074 100644
--- a/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/builtins/TestBuiltin_dfltWarn.java
+++ b/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/builtins/TestBuiltin_dfltWarn.java
@@ -46,7 +46,7 @@ public class TestBuiltin_dfltWarn extends TestBase {
 
     @Test
     public void testdfltWarn6() {
-        assertEval(Output.IgnoreWarningContext, "argv <- list('NaNs produced', quote(log(ifelse(y == 0, 1, y/mu)))); .Internal(.dfltWarn(argv[[1]], argv[[2]]))");
+        assertEval("argv <- list('NaNs produced', quote(log(ifelse(y == 0, 1, y/mu)))); .Internal(.dfltWarn(argv[[1]], argv[[2]]))");
     }
 
     @Test
diff --git a/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/library/stats/TestExternal_rcauchy.java b/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/library/stats/TestExternal_rcauchy.java
deleted file mode 100644
index f909eb9268bf84271a71a98d47b9a9c536c8e89e..0000000000000000000000000000000000000000
--- a/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/library/stats/TestExternal_rcauchy.java
+++ /dev/null
@@ -1,36 +0,0 @@
-/*
- * 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 org.junit.Test;
-
-import com.oracle.truffle.r.test.TestBase;
-
-public class TestExternal_rcauchy extends TestBase {
-    @Test
-    public void testRcauchy() {
-        assertEval("set.seed(42); rcauchy(10, 10, 10)");
-        assertEval("set.seed(42); rcauchy(10, 10, -1)");
-        assertEval("set.seed(42); rcauchy(10, NaN, 10)");
-    }
-}
diff --git a/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/library/stats/TestExternal_rbeta.java b/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/library/stats/TestExternal_rnbinom.java
similarity index 75%
rename from com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/library/stats/TestExternal_rbeta.java
rename to com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/library/stats/TestExternal_rnbinom.java
index f4ab519fd490edcbcb89bb8f9e1f1e6a94b2cf7b..c8385786a2adca7b6873fd5f998a489dbdc135a4 100644
--- a/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/library/stats/TestExternal_rbeta.java
+++ b/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/library/stats/TestExternal_rnbinom.java
@@ -20,16 +20,18 @@
  * or visit www.oracle.com if you need additional information or have any
  * questions.
  */
+
 package com.oracle.truffle.r.test.library.stats;
 
 import org.junit.Test;
 
 import com.oracle.truffle.r.test.TestBase;
 
-public class TestExternal_rbeta extends TestBase {
+public class TestExternal_rnbinom extends TestBase {
     @Test
-    public void testRbeta() {
-        assertEval("set.seed(42); rbeta(10, 10, 10)");
-        assertEval("set.seed(42); rbeta(10, c(0.1, 2:10), c(0.1, 0.5, 0.9, 3:5))");
+    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))");
     }
 }
diff --git a/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/library/stats/TestExternal_rnorm.java b/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/library/stats/TestExternal_rnorm.java
deleted file mode 100644
index 1bd9882bfcde589cdb3fce85d3a8de27d0432d0f..0000000000000000000000000000000000000000
--- a/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/library/stats/TestExternal_rnorm.java
+++ /dev/null
@@ -1,39 +0,0 @@
-/*
- * 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 org.junit.Test;
-
-import com.oracle.truffle.r.test.TestBase;
-
-public class TestExternal_rnorm extends TestBase {
-    @Test
-    public void testRnorm() {
-        assertEval("set.seed(42); rnorm(10, 10, 10)");
-        assertEval("set.seed(42); rnorm('10', 10, 5)");
-        assertEval(Output.IgnoreWarningContext, "set.seed(42); rnorm('aa', 10, 0.5)");
-        assertEval("set.seed(42); rnorm(10, 2:10, c(0.1, 0.5, 0.9))");
-        assertEval("set.seed(42); rnorm(1:10, 2:10, c(0.1, 0.5, 0.9))");
-        assertEval("set.seed(42); rnorm(c(1,2), 11:12, c(0.1, 0.5, 0.9))");
-    }
-}
diff --git a/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/library/stats/TestExternal_runif.java b/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/library/stats/TestExternal_runif.java
deleted file mode 100644
index ad117436f0b49f14a365a15ae38563b7b26ca3fc..0000000000000000000000000000000000000000
--- a/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/library/stats/TestExternal_runif.java
+++ /dev/null
@@ -1,35 +0,0 @@
-/*
- * 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 org.junit.Test;
-
-import com.oracle.truffle.r.test.TestBase;
-
-public class TestExternal_runif extends TestBase {
-    @Test
-    public void testRunif() {
-        assertEval("set.seed(1); runif(5);");
-        assertEval("set.seed(1); runif(5, 10, 2.5);");
-    }
-}
diff --git a/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/library/stats/TestRandGenerationFunctions.java b/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/library/stats/TestRandGenerationFunctions.java
new file mode 100644
index 0000000000000000000000000000000000000000..11898e61ca3b04ff4c2f6eedc78dda28b32b5ab6
--- /dev/null
+++ b/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/library/stats/TestRandGenerationFunctions.java
@@ -0,0 +1,99 @@
+/*
+ * 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.library.stats;
+
+import org.junit.Test;
+
+import com.oracle.truffle.r.test.TestBase;
+
+/**
+ * Tests the rxxx functions against common set of arguments. Each such function may have additional
+ * tests for its specific corner cases if those are not covered here.
+ */
+public class TestRandGenerationFunctions extends TestBase {
+    private static final String[] FUNCTION2_NAMES = {"rnorm", "runif", "rgamma", "rbeta", "rcauchy", "rf", "rlogis", "rweibull", "rchisq", "rwilcox"};
+    private static final String[] FUNCTION2_PARAMS = {
+                    "10, 10, 10",
+                    "20, c(-1, 0, 0.2, 2:5), c(-1, 0, 0.1, 0.9, 3)",
+                    "30, c(NA, 0, NaN, 1/0, -1/0), c(NaN, NaN, NA, 0, 1/0, -1/0)",
+                    "24, c(0.0653, 0.000123, 32e-80, 8833, 79e70), c(0.0653, 0.000123, 32e-80, 8833, 79e70, 0, -1)"
+    };
+
+    @Test
+    public void testFunctions2() {
+        assertEval(Output.IgnoreWhitespace, template("set.seed(1); %0(%1)", FUNCTION2_NAMES, FUNCTION2_PARAMS));
+    }
+
+    @Test
+    public void testFunctions2Infrastructure() {
+        // calculating the size of the result:
+        assertEval("length(runif(c(1,2,3)))");
+        assertEval("length(runif(c('a', 'b', 'b', 'd')))");
+        assertEval("length(runif('3'))");
+        // wrong size argument
+        assertEval(Output.IgnoreWarningContext, "runif('hello')");
+        // empty parameters
+        assertEval("runif(2, numeric(), 2)");
+        assertEval("runif(2, 2, numeric())");
+        // wrong parameters
+        assertEval("runif(-1, 1, 2)");
+    }
+
+    private static final String[] FUNCTION1_NAMES = {"rchisq", "rexp", "rgeom", "rpois", "rt"};
+
+    @Test
+    public void testFunctions1() {
+        assertEval(Output.IgnoreWhitespace, template("set.seed(2); %0(13, c(NA, NaN, 1/0, -1/0, -1, 1, 0.3, -0.5, 0.0653, 0.000123, 32e-80, 8833, 79e70))", FUNCTION1_NAMES));
+        // Note: signrank has loop with 'n' iterations: we have to leave out the large numbers
+        assertEval(Output.IgnoreWhitespace, "set.seed(10); rsignrank(12, c(NA, NaN, 1/0, -1/0, -1, 1, 0.3, -0.6, 0.0653, 0.000123, 32e-80, 10))");
+    }
+
+    @Test
+    public void testFunctions3() {
+        // error: drawn (20) mare than red + blue (5+5)
+        assertEval("rhyper(1, 5, 5, 20)");
+        // error: negative number of balls
+        assertEval("rhyper(1, -5, 5, 20)");
+        // common errors with NA, NaN, Inf
+        assertEval("rhyper(1, NA, 5, 20)");
+        assertEval("rhyper(1, 5, NaN, 20)");
+        assertEval("rhyper(1, 5, 5, 1/0)");
+        assertEval("rhyper(1, 5, 5, -1/0)");
+        // few simple tests (note: rhyper seems to be quite slow even in GnuR).
+        assertEval("set.seed(3); rhyper(3, 10, 10, 5)");
+        assertEval("set.seed(3); rhyper(2, 1000, 1000, 5)");
+        assertEval("set.seed(3); rhyper(3, 10, 79e70, 2)");
+    }
+
+    @Test
+    public void testRmultinom() {
+        assertEval("set.seed(11); rmultinom(10, 5, c(0.1, 0.1, 0.3, 0.2, 0.3))");
+        assertEval("set.seed(11); rmultinom(7, 8, structure(c(0.1, 0.1), .Names=c('a', 'B')))");
+        assertEval("set.seed(12); rmultinom('5', 3.1, c(2, 5, 10))");
+        // test args validation
+        assertEval("rmultinom(1, 1, -0.15)");
+        assertEval(Output.IgnoreErrorContext, Output.IgnoreErrorMessage, "rmultinom('string', 1, 0.15)");
+        assertEval("rmultinom(1, NA, 0.2)");
+        assertEval("rmultinom(NA, 1, 0.2)");
+    }
+}
diff --git a/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/parser/TestParser.java b/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/parser/TestParser.java
index 521c51ec2b9d97d79ec160760dd8afa129ef6348..eec0fb6933b2b887143e19524bb5c7f5fcf6ab09 100644
--- a/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/parser/TestParser.java
+++ b/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/parser/TestParser.java
@@ -51,6 +51,16 @@ public class TestParser extends TestBase {
         assertEval("10^2^2");
     }
 
+    @Test
+    public void testDoubleLiterals() {
+        assertEval("0x1.1p2");
+        assertEval("0x1p2");
+        assertEval("0x0p0");
+        assertEval("0x1.aP2");
+        assertEval("0xa.p2");
+        assertEval("0xa.bp1i");
+    }
+
     @Test
     public void testSpaceEscapeSequence() {
         assertEval("\"\\ \" == \" \"");
diff --git a/mx.fastr/copyrights/gnu_r_gentleman_ihaka.copyright.star.regex b/mx.fastr/copyrights/gnu_r_gentleman_ihaka.copyright.star.regex
index 5613605b4c037af996113ee669b64fb56aa847d9..207e33d41d26833be355e95a9f9e30a0ef28b135 100644
--- a/mx.fastr/copyrights/gnu_r_gentleman_ihaka.copyright.star.regex
+++ b/mx.fastr/copyrights/gnu_r_gentleman_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\) 1995, 1996, 1997  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\) (?:[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.*
\ 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\) 1995, 1996(?:, 1997)?  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\) (?:[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/overrides b/mx.fastr/copyrights/overrides
index d76934e4506834d6521c3efa1b2386f4a4ef143a..34b4bca629f2ceea3857c3c258899c620e4673e9 100644
--- a/mx.fastr/copyrights/overrides
+++ b/mx.fastr/copyrights/overrides
@@ -30,24 +30,31 @@ com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/methods/MethodsLis
 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/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/RCauchy.java,gnu_r_ihaka_core.copyright
 com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/stats/Cdist.java,gnu_r_gentleman_ihaka.copyright
 com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/stats/CompleteCases.java,gnu_r_gentleman_ihaka2.copyright
 com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/stats/Covcor.java,gnu_r.copyright
 com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/stats/Cutree.java,gnu_r.core.copyright
+com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/stats/Signrank.java,gnu_r.core.copyright
 com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/stats/Dbinom.java,gnu_r.copyright
 com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/stats/DoubleCentre.java,gnu_r.core.copyright
 com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/stats/DPQ.java,gnu_r.core.copyright
+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/MathConstants.java,gnu_r.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/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/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/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/Rnorm.java,gnu_r.copyright
 com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/stats/SplineFunctions.java,gnu_r_splines.copyright
@@ -55,6 +62,18 @@ com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/stats/StatsFunctio
 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/StatsUtil.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/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/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/RExp.java,gnu_r_ihaka_core.copyright
+com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/stats/RGeom.java,gnu_r_ihaka_core.copyright
+com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/stats/RNchisq.java,gnu_r.copyright
+com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/stats/Wilcox.java,gnu_r.core.copyright
+com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/stats/RWeibull.java,gnu_r_ihaka_core.copyright
 com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/tools/DirChmod.java,gnu_r.copyright
 com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/tools/ToolsText.java,gnu_r.copyright
 com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/utils/CountFields.java,gnu_r.copyright