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 8a55565f261df940882ccef50c475c1111ac21b1..b9872eff5c71a086460ac1ff5db0f35534747a82 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
@@ -18,12 +18,10 @@ import com.oracle.truffle.r.runtime.rng.RandomNumberNode;
 public final class Rnorm implements RandFunction2_Double {
 
     private static final double BIG = 134217728;
-    private double[] randomVals;
 
     @Override
     public void init(int length, RandomNumberNode randNode) {
         RRNG.getRNGState();
-        randomVals = randNode.executeDouble(length * 2);
     }
 
     @Override
@@ -34,7 +32,7 @@ public final class Rnorm implements RandFunction2_Double {
     @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 * randomVals[index * 2]) + randomVals[index * 2 + 1];
+        double u1 = (int) (BIG * randomNode.executeSingleDouble()) + randomNode.executeSingleDouble();
         double rand = Random2.qnorm5(u1 / BIG, 0.0, 1.0, true, false);
         return rand * sigma + mu;
     }
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 c5fb0cdcd9a67cbf042ef4037957042254b5e3ca..0536885f7ec6dbdd5a694c6a4ef9891d8b50ebbe 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
@@ -30,7 +30,7 @@ public final class Runif implements RandFunction2_Double {
 
     @Override
     public boolean hasCustomRandomGeneration() {
-        return false;
+        return true;
     }
 
     @Override
@@ -38,6 +38,6 @@ public final class Runif implements RandFunction2_Double {
         if (!RRuntime.isFinite(min) || !RRuntime.isFinite(max) || max < min) {
             return StatsUtil.mlError();
         }
-        return min + random * (max - min);
+        return min + randomNode.executeSingleDouble() * (max - min);
     }
 }
diff --git a/com.oracle.truffle.r.runtime.ffi/src/com/oracle/truffle/r/runtime/ffi/jni/CallRFFIHelper.java b/com.oracle.truffle.r.runtime.ffi/src/com/oracle/truffle/r/runtime/ffi/jni/CallRFFIHelper.java
index 10366ff26f49c8348d3c1b6a473b93cc06fddc44..5849eeabcc7cd2fcd6e7d881864ba24a800d6020 100644
--- a/com.oracle.truffle.r.runtime.ffi/src/com/oracle/truffle/r/runtime/ffi/jni/CallRFFIHelper.java
+++ b/com.oracle.truffle.r.runtime.ffi/src/com/oracle/truffle/r/runtime/ffi/jni/CallRFFIHelper.java
@@ -1279,7 +1279,7 @@ public class CallRFFIHelper {
         if (RFFIUtils.traceEnabled()) {
             RFFIUtils.traceUpCall("putRNGstate");
         }
-        RRNG.updateDotRandomSeed();
+        RRNG.putRNGState();
     }
 
     public static double unifRand() {
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 54f73039c58be23c64efd44a15019eaff5f19c71..38c7c2c87dad331f515cb30d81b1f9520637bb23 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
@@ -491,7 +491,7 @@ public final class RError extends RuntimeException {
         SAME_NUMBER_ROWS("'%s' and '%s' must have the same number of rows"),
         EXACT_SINGULARITY("exact singularity in '%s'"),
         SINGULAR_SOLVE("singular matrix '%s' in solve"),
-        SEED_TYPE(".Random.seed is not an integer vector but of type '%s'"),
+        SEED_TYPE("'.Random.seed' is not an integer vector but of type '%s', so ignored"),
         INVALID_NORMAL_TYPE_IN_RGNKIND("invalid Normal type in 'RNGkind'"),
         INVALID_USE("invalid use of '%s'"),
         FORMAL_MATCHED_MULTIPLE("formal argument \"%s\" matched by multiple actual arguments"),
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 12918a1ed0ee2629f5a3919fd483bbc2c5dc28b7..e0eeb827214237504345ef90b0d8fe2f98849e83 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,10 +11,10 @@
  */
 package com.oracle.truffle.r.runtime.rng;
 
-import com.oracle.truffle.r.runtime.rng.RRNG.RandomNumberGenerator;
-
 public abstract class RNGInitAdapter implements RandomNumberGenerator {
 
+    protected static final double I2_32M1 = 2.3283064365386963e-10;
+
     // TODO: it seems like GNU R this is shared between the generators (does it matter?)
     protected final int[] iSeed = new int[625];
 
@@ -25,4 +25,18 @@ public abstract class RNGInitAdapter implements RandomNumberGenerator {
         }
         fixupSeeds(false);
     }
+
+    /**
+     * Ensure 0 and 1 are never returned from rand generation algorithm.
+     */
+    protected static double fixup(double x) {
+        /* transcribed from GNU R, RNG.c (fixup) */
+        if (x <= 0.0) {
+            return 0.5 * I2_32M1;
+        }
+        // removed fixup for 1.0 since x is in [0,1).
+        // TODO Since GnuR does include this is should we not for compatibility (probably).
+        // if ((1.0 - x) <= 0.0) return 1.0 - 0.5 * I2_32M1;
+        return x;
+    }
 }
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 cd34827aaab07653be5e5c24b47a439684f1118c..56ab040453ffb9cfe867a2aed314fdfccd1876f8 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
@@ -16,7 +16,6 @@ import java.util.function.Supplier;
 import com.oracle.truffle.api.CompilerDirectives.CompilationFinal;
 import com.oracle.truffle.api.CompilerDirectives.TruffleBoundary;
 import com.oracle.truffle.r.runtime.RError;
-import com.oracle.truffle.r.runtime.RInternalError;
 import com.oracle.truffle.r.runtime.RRuntime;
 import com.oracle.truffle.r.runtime.context.RContext;
 import com.oracle.truffle.r.runtime.data.RDataFactory;
@@ -26,7 +25,6 @@ import com.oracle.truffle.r.runtime.data.RNull;
 import com.oracle.truffle.r.runtime.data.RPromise;
 import com.oracle.truffle.r.runtime.data.RTypedValue;
 import com.oracle.truffle.r.runtime.env.REnvironment;
-import com.oracle.truffle.r.runtime.env.REnvironment.PutException;
 import com.oracle.truffle.r.runtime.ffi.RFFIFactory;
 import com.oracle.truffle.r.runtime.rng.mm.MarsagliaMulticarry;
 import com.oracle.truffle.r.runtime.rng.mt.MersenneTwister;
@@ -101,28 +99,7 @@ public class RRNG {
     private static final Kind DEFAULT_KIND = Kind.MERSENNE_TWISTER;
     private static final NormKind DEFAULT_NORM_KIND = NormKind.INVERSION;
     private static final String RANDOM_SEED = ".Random.seed";
-    public static final double I2_32M1 = 2.3283064365386963e-10;
     private static final double UINT_MAX = (double) Integer.MAX_VALUE * 2;
-    @CompilationFinal private static final int[] NO_SEEDS = new int[0];
-
-    /**
-     * The (logically private) interface that a random number generator must implement.
-     */
-    public interface RandomNumberGenerator {
-        void init(int seed);
-
-        void fixupSeeds(boolean initial);
-
-        int[] getSeeds();
-
-        double[] genrandDouble(int count);
-
-        Kind getKind();
-
-        int getNSeed();
-
-        void setISeed(int[] seeds);
-    }
 
     public static final class ContextStateImpl implements RContext.ContextState {
         private RandomNumberGenerator currentGenerator;
@@ -149,10 +126,11 @@ public class RRNG {
          */
         @TruffleBoundary
         void updateCurrentGenerator(RandomNumberGenerator newRng, boolean saveState) {
-            this.currentGenerator = newRng;
             this.allGenerators[newRng.getKind().ordinal()] = newRng;
             if (saveState) {
-                getRNGState();
+                getRNGState();  // updates this.currentGenerator
+                // Check if the what will be soon previous generator is not corrupted, otherwise
+                // generate the seed again for our newRng
                 double u = unifRand();
                 if (u < 0.0 || u > 1.0) {
                     RError.warning(RError.NO_CALLER, RError.Message.GENERIC, "someone corrupted the random-number generator: re-initializing");
@@ -160,8 +138,10 @@ public class RRNG {
                 } else {
                     initGenerator(newRng, (int) (u * UINT_MAX));
                 }
-                updateDotRandomSeed();
-
+                this.currentGenerator = newRng;
+                putRNGState();
+            } else {
+                this.currentGenerator = newRng;
             }
         }
 
@@ -184,8 +164,7 @@ public class RRNG {
         void updateCurrentNormKind(NormKind normKind, boolean saveState) {
             currentNormKind = normKind;
             if (saveState) {
-                getRNGState();
-                updateDotRandomSeed();
+                putRNGState();
             }
         }
 
@@ -223,7 +202,7 @@ public class RRNG {
      * Ask the current generator for a random double. (cf. {@code unif_rand} in RNG.c.
      */
     public static double unifRand() {
-        return currentGenerator().genrandDouble(1)[0];
+        return currentGenerator().genrandDouble();
     }
 
     /**
@@ -239,7 +218,7 @@ public class RRNG {
     public static void doSetSeed(int seed, int kindAsInt, int normKindAsInt) {
         getRNGKind(RNull.instance);
         changeKindsAndInitGenerator(seed, kindAsInt, normKindAsInt);
-        updateDotRandomSeed();
+        putRNGState();
     }
 
     /**
@@ -279,18 +258,6 @@ public class RRNG {
         } // otherwise the current one stays
     }
 
-    public static double fixup(double x) {
-        /* transcribed from GNU R, RNG.c (fixup) */
-        /* ensure 0 and 1 are never returned */
-        if (x <= 0.0) {
-            return 0.5 * I2_32M1;
-        }
-        // removed fixup for 1.0 since x is in [0,1).
-        // TODO Since GnuR does include this is should we not for compatibility (probably).
-        // if ((1.0 - x) <= 0.0) return 1.0 - 0.5 * I2_32M1;
-        return x;
-    }
-
     private static Kind intToKind(int kindAsInt) {
         if (kindAsInt < 0 || kindAsInt >= Kind.VALUES.length || !Kind.VALUES[kindAsInt].isAvailable()) {
             throw RError.error(RError.NO_CALLER, RError.Message.RNG_NOT_IMPL_KIND, kindAsInt);
@@ -321,19 +288,6 @@ public class RRNG {
         return seed;
     }
 
-    @TruffleBoundary
-    public static void updateDotRandomSeed() {
-        int[] seeds = currentGenerator().getSeeds();
-        int lenSeeds = currentGenerator().getNSeed();
-        int[] data = new int[lenSeeds + 1];
-        data[0] = currentKind().ordinal() + 100 * currentNormKind().ordinal();
-        for (int i = 0; i < lenSeeds; i++) {
-            data[i + 1] = seeds[i];
-        }
-        RIntVector vector = RDataFactory.createIntVector(data, RDataFactory.COMPLETE_VECTOR);
-        REnvironment.globalEnv().safePut(RANDOM_SEED, vector);
-    }
-
     /**
      * Create a random integer.
      */
@@ -354,6 +308,10 @@ public class RRNG {
         getContextState().updateCurrentNormKind(DEFAULT_NORM_KIND, false);
     }
 
+    /**
+     * Sets the current generator according to the flag under index 0 of given vector
+     * {@code seedsObj}.
+     */
     private static void getRNGKind(Object seedsObj) {
         Object seeds = seedsObj;
         if (seeds == RNull.instance) {
@@ -371,12 +329,13 @@ public class RRNG {
         } else {
             assert seeds != RMissing.instance;
             assert seeds instanceof RTypedValue;
-            RError.warning(RError.NO_CALLER, RError.Message.SEED_TYPE, "'.Random.seed' is not an integer vector but of type '%s', so ignored", ((RTypedValue) seeds).getRType().getName());
+            RError.warning(RError.NO_CALLER, RError.Message.SEED_TYPE, ((RTypedValue) seeds).getRType().getName());
             handleInvalidSeed();
             return;
         }
         if (tmp == RRuntime.INT_NA || tmp < 0 || tmp > 1000) {
-            RError.warning(RError.NO_CALLER, RError.Message.GENERIC, "'.Random.seed[1]' is not a valid integer, so ignored");
+            String type = seeds instanceof RTypedValue ? ((RTypedValue) seeds).getRType().getName() : "unknown";
+            RError.warning(RError.NO_CALLER, RError.Message.SEED_TYPE, type);
             handleInvalidSeed();
             return;
         }
@@ -404,6 +363,11 @@ public class RRNG {
         getContextState().updateCurrentNormKind(newNormKind, false);
     }
 
+    /**
+     * Loads the state of RNG from global environment variable {@code .Random.seed}. This should be
+     * invoked before any random numbers generation as the user may have directly changed the
+     * {@code .Random.seed} variable and the current generator and/or its seed should be updated.
+     */
     @TruffleBoundary
     public static void getRNGState() {
         Object seedsObj = getDotRandomSeed();
@@ -418,7 +382,8 @@ public class RRNG {
                 RIntVector seedsVec = (RIntVector) seedsObj;
                 seeds = seedsVec.getDataWithoutCopying();
             } else {
-                throw RInternalError.shouldNotReachHere();
+                // seedsObj is not valid, which should have been reported and fixed in getRNGKind
+                return;
             }
 
             if (seeds.length > 1 && seeds.length < (currentGenerator().getNSeed() + 1)) {
@@ -432,22 +397,33 @@ public class RRNG {
         }
     }
 
+    /**
+     * Saves the state of RNG into global environment under {@code .Random.seed}. This should be
+     * invoked after any random numbers generation.
+     */
     @TruffleBoundary
     public static void putRNGState() {
-        int lenSeed = getContextState().currentGenerator.getNSeed();
-        int[] seeds = new int[lenSeed + 1];
-        seeds[0] = currentKindAsInt() + 100 * currentNormKindAsInt();
-        int[] currentGeneratorSeeds = currentGenerator().getSeeds();
-        for (int i = 0; i < lenSeed; i++) {
-            seeds[i + 1] = currentGeneratorSeeds[i];
+        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];
         }
 
-        currentGenerator().setISeed(seeds);
-        RIntVector seedsVector = RDataFactory.createIntVector(seeds, true);
-        try {
-            REnvironment.globalEnv().put(RANDOM_SEED, seedsVector);
-        } catch (PutException e) {
-            throw RInternalError.shouldNotReachHere("Cannot set .Random.seed in global environment");
+        if (!canReusePrev) {
+            RIntVector vector = RDataFactory.createIntVector(data, RDataFactory.COMPLETE_VECTOR);
+            REnvironment.globalEnv().safePut(RANDOM_SEED, vector);
         }
     }
 }
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
new file mode 100644
index 0000000000000000000000000000000000000000..3ca1a0f164238b5dd15d32ab1029ce9147346602
--- /dev/null
+++ b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/rng/RandomNumberGenerator.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) 1995-2012, The R Core Team
+ * Copyright (c) 2003, The R Foundation
+ * Copyright (c) 2014, 2016, Oracle and/or its affiliates
+ *
+ * All rights reserved.
+ */
+package com.oracle.truffle.r.runtime.rng;
+
+import com.oracle.truffle.r.runtime.rng.RRNG.Kind;
+
+/**
+ * Interface for a random number generator algorithm.
+ */
+public interface RandomNumberGenerator {
+    void init(int seed);
+
+    void fixupSeeds(boolean initial);
+
+    int[] getSeeds();
+
+    double genrandDouble();
+
+    Kind getKind();
+
+    /**
+     * Returns number of seed values this generator requires.
+     */
+    int getNSeed();
+
+    /**
+     * Sets array which contains current generator flag under index 0 and seeds for random
+     * generation under the other indices.
+     */
+    void setISeed(int[] seeds);
+}
diff --git a/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/rng/RandomNumberNode.java b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/rng/RandomNumberNode.java
index f77dda2729d47d7406f9bc68719cc8e71a8e2faa..fa41460b92916fa4b52d888a6f622800bb128076 100644
--- a/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/rng/RandomNumberNode.java
+++ b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/rng/RandomNumberNode.java
@@ -31,11 +31,15 @@ public final class RandomNumberNode extends RBaseNode {
     private final ValueProfile generatorClassProfile = ValueProfile.createClassProfile();
 
     public double[] executeDouble(int count) {
-        return generatorClassProfile.profile(generatorProfile.profile(RRNG.currentGenerator())).genrandDouble(count);
+        double[] result = new double[count];
+        for (int i = 0; i < count; i++) {
+            result[i] = executeSingleDouble();
+        }
+        return result;
     }
 
     public double executeSingleDouble() {
-        return generatorClassProfile.profile(generatorProfile.profile(RRNG.currentGenerator())).genrandDouble(1)[0];
+        return generatorClassProfile.profile(generatorProfile.profile(RRNG.currentGenerator())).genrandDouble();
     }
 
     public static RandomNumberNode create() {
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 85cde953ade8f95162da7b1bbe29f0fa5efdae11..697e3c65ac7ca598bbbd35eef9571477566915a8 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
@@ -13,7 +13,6 @@ package com.oracle.truffle.r.runtime.rng.mm;
 
 import com.oracle.truffle.api.CompilerDirectives.TruffleBoundary;
 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;
 
 /**
@@ -49,20 +48,16 @@ public final class MarsagliaMulticarry extends RNGInitAdapter {
     }
 
     @Override
-    public double[] genrandDouble(int count) {
+    public double genrandDouble() {
         int state0 = iSeed[0];
         int state1 = iSeed[1];
-        double[] result = new double[count];
-        for (int i = 0; i < count; i++) {
-            state0 = 36969 * (state0 & 0177777) + (state0 >>> 16);
-            state1 = 18000 * (state1 & 0177777) + (state1 >>> 16);
-            int x = (state0 << 16) ^ (state1 & 0177777);
-            double d = (x & 0xffffffffL) * RRNG.I2_32M1;
-            result[i] = RRNG.fixup(d); /* in [0,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;
-        return result;
+        return fixup(d); /* in [0,1) */
     }
 
     @Override
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 ddc4d8a7d864fc4e840ee814dcbaaea072e56167..b084498c040d708c01f8e64c056f9a29a29ff9c2 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
@@ -80,6 +80,15 @@ public final class MersenneTwister extends RNGInitAdapter {
     private static final int TEMPERING_MASK_B = 0x9d2c5680;
     private static final int TEMPERING_MASK_C = 0xefc60000;
 
+    /*
+     * This generator can efficiently generate many random numbers in one go, upon each call to
+     * genrandDouble() we take the next random value from 'buffer'. If the buffer is empty, we fill
+     * it.
+     */
+    private static final int BUFFER_SIZE = N;
+    private final double[] buffer = new double[BUFFER_SIZE];
+    private int bufferIndex = BUFFER_SIZE;
+
     /**
      * The array for the state vector. In GnuR, the state array is common to all algorithms (named
      * {@code dummy}), and the zero'th element is the number of seeds, but the algorithm uses
@@ -96,14 +105,19 @@ public final class MersenneTwister extends RNGInitAdapter {
     // to keep variable naming (somewhat) consistent with GNU R
     private int[] dummy = iSeed;
 
-    /**
-     * Following GnuR this is set to {@code N+1} to indicate unset if MT_genrand is called, although
-     * that condition never appears to happen in practice, as {@code RNG_init}, cf. {@link #init} is
-     * always called first. N.B. This value has a relationship with {@code dummy0} in that it is
-     * always loaded from {@code dummy0} in {@link #genrandDouble(int)} and the updated value is
-     * stored back in {@code dummy[0]}.
-     */
-    private int mti = N + 1;
+    @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.
@@ -130,6 +144,7 @@ public final class MersenneTwister extends RNGInitAdapter {
             iSeed[i] = seed;
         }
         fixupSeeds(true);
+        bufferIndex = BUFFER_SIZE;
     }
 
     @Override
@@ -154,90 +169,63 @@ public final class MersenneTwister extends RNGInitAdapter {
 
     /**
      * The actual generating method, essentially transcribed from MT_genrand in GnuR RNG.c.
-     * Additional method have been introduced for clarity and the import
-     * {@link com.oracle.truffle.api.CompilerDirectives.TruffleBoundary} annotation on
-     * {@link #generateNewNumbers()}.
      */
     @Override
-    public double[] genrandDouble(int count) {
-        int localDummy0 = dummy[0];
-        int localMti = mti;
-        double[] result = new double[count];
-
-        localMti = localDummy0;
-        // It appears that this never happens
-        // sgenrand(4357);
-        RInternalError.guarantee(localMti != N + 1);
-
-        int pos = 0;
-        while (true) {
-            int loopCount = Math.min(count - pos, N - localMti);
-            for (int i = 0; i < loopCount; i++) {
-                int y = getMt(localMti + i);
-                /* Tempering */
-                y ^= (y >>> 11);
-                y ^= (y << 7) & TEMPERING_MASK_B;
-                y ^= (y << 15) & TEMPERING_MASK_C;
-                y ^= (y >>> 18);
-                result[pos + i] = ((y + Integer.MIN_VALUE) - (double) Integer.MIN_VALUE) * RRNG.I2_32M1;
-            }
-            for (int i = 0; i < loopCount; i++) {
-                result[pos + i] = RRNG.fixup(result[pos + i]);
-            }
-            localMti += loopCount;
-            pos += loopCount;
-
-            if (pos == count) {
-                break;
+    public double genrandDouble() {
+        if (bufferIndex == BUFFER_SIZE) {
+            int localDummy0 = dummy[0];
+            int localMti = localDummy0;
+            // It appears that this never happens
+            // sgenrand(4357);
+            RInternalError.guarantee(localMti != N + 1);
+
+            int pos = 0;
+            while (true) {
+                int loopCount = Math.min(BUFFER_SIZE - pos, N - localMti);
+                for (int i = 0; i < loopCount; i++) {
+                    int y = getMt(localMti + i);
+                    /* Tempering */
+                    y ^= (y >>> 11);
+                    y ^= (y << 7) & TEMPERING_MASK_B;
+                    y ^= (y << 15) & TEMPERING_MASK_C;
+                    y ^= (y >>> 18);
+                    buffer[pos + i] = ((y + Integer.MIN_VALUE) - (double) Integer.MIN_VALUE) * I2_32M1;
+                }
+                for (int i = 0; i < loopCount; i++) {
+                    buffer[pos + i] = fixup(buffer[pos + i]);
+                }
+                localMti += loopCount;
+                pos += loopCount;
+
+                if (pos == BUFFER_SIZE) {
+                    break;
+                }
+                /* generate N words at one time */
+                int kk;
+                for (kk = 0; kk < N - M; kk++) {
+                    int y2y = (getMt(kk) & UPPERMASK) | (getMt(kk + 1) & LOWERMASK);
+                    setMt(kk, getMt(kk + M) ^ (y2y >>> 1) ^ mag01(y2y & 0x1));
+                }
+                for (; kk < N - 1; kk++) {
+                    int y2y = (getMt(kk) & UPPERMASK) | (getMt(kk + 1) & LOWERMASK);
+                    setMt(kk, getMt(kk + (M - N)) ^ (y2y >>> 1) ^ mag01(y2y & 0x1));
+                }
+                int y2y = (getMt(N - 1) & UPPERMASK) | (getMt(0) & LOWERMASK);
+                setMt(N - 1, getMt(M - 1) ^ (y2y >>> 1) ^ mag01(y2y & 0x1));
+
+                localMti = 0;
             }
-            /* generate N words at one time */
-            int kk;
-            for (kk = 0; kk < N - M; kk++) {
-                int y2y = (getMt(kk) & UPPERMASK) | (getMt(kk + 1) & LOWERMASK);
-                setMt(kk, getMt(kk + M) ^ (y2y >>> 1) ^ mag01(y2y & 0x1));
-            }
-            for (; kk < N - 1; kk++) {
-                int y2y = (getMt(kk) & UPPERMASK) | (getMt(kk + 1) & LOWERMASK);
-                setMt(kk, getMt(kk + (M - N)) ^ (y2y >>> 1) ^ mag01(y2y & 0x1));
-            }
-            int y2y = (getMt(N - 1) & UPPERMASK) | (getMt(0) & LOWERMASK);
-            setMt(N - 1, getMt(M - 1) ^ (y2y >>> 1) ^ mag01(y2y & 0x1));
-
-            localMti = 0;
+            localDummy0 = localMti;
+            dummy[0] = localDummy0;
+            bufferIndex = 0;
         }
-        localDummy0 = localMti;
-        mti = localMti;
-        dummy[0] = localDummy0;
-        return result;
+        return buffer[bufferIndex++];
     }
 
     private static int mag01(int v) {
         return (v & 1) != 0 ? MATRIXA : 0;
     }
 
-    @TruffleBoundary
-    private void generateNewNumbers() {
-        int y2y;
-        int kk;
-
-        // It appears that this never happens
-        // sgenrand(4357);
-        RInternalError.guarantee(mti != N + 1);
-
-        for (kk = 0; kk < N - M; kk++) {
-            y2y = (getMt(kk) & UPPERMASK) | (getMt(kk + 1) & LOWERMASK);
-            setMt(kk, getMt(kk + M) ^ (y2y >>> 1) ^ mag01(y2y & 0x1));
-        }
-        for (; kk < N - 1; kk++) {
-            y2y = (getMt(kk) & UPPERMASK) | (getMt(kk + 1) & LOWERMASK);
-            setMt(kk, getMt(kk + (M - N)) ^ (y2y >>> 1) ^ mag01(y2y & 0x1));
-        }
-        y2y = (getMt(N - 1) & UPPERMASK) | (getMt(0) & LOWERMASK);
-        setMt(N - 1, getMt(M - 1) ^ (y2y >>> 1) ^ mag01(y2y & 0x1));
-
-        mti = 0;
-    }
-
     @Override
     public Kind getKind() {
         return Kind.MERSENNE_TWISTER;
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 994950b30fb9b6d43ef11c791c707249dcbf507d..79a8117b3b8c6acc7554842a53d368ffc3baf2c0 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
@@ -130,12 +130,8 @@ public final class UserRNG extends RNGInitAdapter {
     }
 
     @Override
-    public double[] genrandDouble(int count) {
-        double[] result = new double[count];
-        for (int i = 0; i < count; i++) {
-            result[i] = userRngRFFI.rand();
-        }
-        return result;
+    public double genrandDouble() {
+        return userRngRFFI.rand();
     }
 
     @Override
diff --git a/com.oracle.truffle.r.test.cran/r/install.cran.packages.R b/com.oracle.truffle.r.test.cran/r/install.cran.packages.R
index 6f6ac20367fb943b12546ca5e3f58b01cbf8d7c8..a92c95ff4a23de6e5b9ec66b9e0a38d7e6d14ade 100644
--- a/com.oracle.truffle.r.test.cran/r/install.cran.packages.R
+++ b/com.oracle.truffle.r.test.cran/r/install.cran.packages.R
@@ -537,6 +537,15 @@ install.suggests <- function(pkgnames) {
 	for (pkgname in pkgnames) {
 		suggests <- install.order(avail.pkgs, avail.pkgs[pkgname, ], "suggests")
 		if (length(suggests) > 0) {
+			if (is.fastr() && !ignore.blacklist) {
+				# no point in trying to install blacklisted packages (which are likely)
+				blacklist <- get.blacklist()
+				nsuggests <- suggests[!suggests %in% blacklist]
+				if (length(nsuggests) != length(suggests)) {
+					cat("not installing Suggests of:", pkgname, ", one or more is blacklisted", "\n")
+					return()
+				}
+			}
 			dep.status <- install.status[suggests]
 			# three cases:
 			# 1. all TRUE: nothing to do all already installed ok
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 768d18e36da0bccd498c40b6ee75af81d0e98550..d8b7dc03e66e39887804ac7697a2684e9e9a96be 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
@@ -114716,6 +114716,17 @@ Error: unexpected '*' in:
 #{ library("testrffi", lib.loc = "tmptest/com.oracle.truffle.r.test.rpackages"); a <- c(1L,2L,3L); x <- rffi.iterate_iptr(a); detach("package:testrffi"); x }
 [1] 1 2 3
 
+
+[[2]]
+[1] 1 2 3 4
+
+[[3]]
+[1] 0.0 0.2 0.4 0.6
+
+[[4]]
+[1]  TRUE FALSE FALSE FALSE
+
+
 ##com.oracle.truffle.r.test.rffi.TestRFFIPackage.testRFFI11#
 #{ library("testrffi", lib.loc = "tmptest/com.oracle.truffle.r.test.rpackages"); x <- rffi.dotCModifiedArguments(c(0,1,2,3)); detach("package:testrffi"); x }
 [[1]]
@@ -114911,6 +114922,142 @@ NULL
  [1] 0.45336386 0.38848030 0.94576608 0.11726267 0.21542351 0.08672997
  [7] 0.35201276 0.16919220 0.93579263 0.26084486
 
+##com.oracle.truffle.r.test.rng.TestRRNG.testDirectReadingSeed#
+#invisible(runif(1)); length(.Random.seed)
+[1] 626
+
+##com.oracle.truffle.r.test.rng.TestRRNG.testDirectReadingSeed#
+#set.seed(42); .Random.seed
+  [1]         403         624   507561766  1260545903  1362917092 -1772566379
+  [7] -1344458670  1072028587 -1293707536  1708789297 -1333339586   256895399
+ [13]   998413756  -555191411 -1047547670   -50950813 -1543487672 -1766763351
+ [19]    32923734  1971684063  1718493076 -1117926011   890393730 -1032174053
+ [25]   932479648 -1892763103 -1040205458   262148887 -1220643732  1566094973
+ [31]  -137659622  1045161427 -1555709704   178265753 -1033943674 -1034388913
+ [37] -1721830332 -1749741963 -1137867598 -2065544053   866474576   458187281
+ [43]  1218274462 -2000447353   199687964  1107998061   590795082  -858760637
+ [49]  -240079192   839017609 -1886488906 -1479389761  1595536628  1848478565
+ [55]   368165090 -1706758405  -128901632   360384001  2027084750  1372682743
+ [61] -1578682932 -1716686755  1324659578  1519053491  2044463192  -906549639
+ [67]  1851192294 -1175847633 -1083563612  -849984427   333580562  1871261035
+ [73]  1972555184  1756407281  1943215870 -1751074969  1282021500 -1397758131
+ [79]   518529450 -1421699293   488820232  -413309847  1749794070   441878687
+ [85]    81427028  1971206469 -1203675838   995493851  -366646944  -810597919
+ [91]  2006003246  1288196311  -111499476  -280946115    -4973606    75390867
+ [97]  1671430072  -422306215 -1145056698  -393285617  1823866628  1253337653
+[103]  1712504178  1846705739 -1820069616  -990520879   247466334 -1717615033
+[109]  1633935836  -246413011  1455137290 -1652210685   741252456  1555715145
+[115]   197538678 -1312148609  -687362124  1153947429   286861730   568692923
+[121]  1575576768  1925410241  1087549582  1279039415 -1208956788  1317778461
+[127] -1306414022   257836147  1550427928    86967865 -1875779418  -520138001
+[133]  1989839972  1598521365  1842848210 -1967767765 -1806646160 -1558774351
+[139] -1040440386  1215776039  1529633596 -1637672179  -121023894  -992976669
+[145] -1867768632 -1273940951  1167448534   786779743 -2131127020 -1987943163
+[151]   563160578  1714129307 -1871376352 -1347450463   590308078  -135901545
+[157] -2080269844  1678065149 -1705673574  1784846675  -871301512  1157619225
+[163]   491069190   301147599  -563099196 -1769503243  -230115790  1806462987
+[169]  1792100304  1913393553    35614238 -1176456185  -165968740   -27190035
+[175] -1087819062  1583082947   678644776 -1957034999   760393782   778033471
+[181]  -636999052   757457637  -155102622 -1134562693 -1432327296   862688641
+[187]   960447822  1400730999 -1343939764 -1742358563  2020046074   549674547
+[193] -2039609896  1111401977  -527331994  -970823505  -779241692 -1209238571
+[199]  -964822382  1395462379  -170034384 -1664281231   264366206  1603506919
+[205] -1702273540   398593741  -269270230 -1017124189  1029450632   -57883671
+[211]   647280278   686937119  -443846700  1428836549 -1446924606  1958398811
+[217] -1052543264 -1494249119  1771722670 -1095103401   972246188   258286013
+[223] -1737515686  1505268499  -883376840   350445017 -1548801082   608508815
+[229] -1454615420  -957455947  -913346830   527442379     5070480 -1974335151
+[235]  -142896418   122151367  1556997980 -1392643923  1564443530  1762940803
+[241] -2059486488 -1650363447  -520885002  1934835455  -757373644  1661447845
+[247]  1604991778  2071204923  -717868480 -1355580095  1725471246  -179039433
+[253]  -863752692 -1438942307  -762972742  1484404723  1185490072  1357252025
+[259]  2083912230   789790319  -352083484    50673557  -426437806  1252893355
+[265]  1090056688 -1651315407 -1847300802  -625631065   -46063428  1015857805
+[271]  1696986090  -525257629   569571912 -2138041431  1476940630  1044126175
+[277]   -45086060  -197788539  1234368386  1489227035  -749691488  -315664095
+[283] -1349383058   251890199 -1108361364    86033789 -1966965222  2084588755
+[289]   272055288   104766873  -876742522  -985345713  1208721220  -408355467
+[295]   346482610  -350383221  1522021712   898089233 -2087422050  1603587975
+[301]  -398783972    15107181  -239168438  -680623805 -1588532824   860922761
+[307]  -748033610 -1771805505  -331259916  -500352411 -1533811742   820114939
+[313] -1804945152   -35969791 -1906397490  2139123959   277741772  2022506333
+[319] -1321388422  1078120883 -1411710120 -1058724487  1071589094 -1584278481
+[325] -1648603996   743551829  1457318930 -1292372885  -597481296 -1389853455
+[331]  1025749502  2006806119   907256700  -259836339  2032231594   377765411
+[337]   -47150840 -1076157591  -424628202  1686380447  1392993620  1113942085
+[343] -1178271678 -1006203173  -581139360  2049892577   433488174   377669591
+[349]  1924592172   418916669 -1039261990  1002030739   158104248 -1999528615
+[355]  -768506554  1521633039  -177362428  -998811339 -1135665038  -260782773
+[361]  1087491088  1533884625   -81126306  1619492167 -1423774500 -1109731283
+[367]   -43621110 -2094372093 -1687562136 -1406692535  1903470198  1834175103
+[373]   284826292  1716946469  -566342494  1852413883  1593704384  -148730687
+[379]   881951630    -4026697  1052939148 -1227209955  -984795334   568142707
+[385] -2067553768  -503577287  -934472794  1667115503 -2072529052  -544084203
+[391]  1612022994 -1916008917  -287563920 -1823613775  -968902978 -1274348505
+[397] -1212094916  -681219571   212178282   513345507  1305794504   -97651927
+[403] -1622291242  1367991647   829521940  -612854779  1930938626   675483803
+[409] -1238947040    95299745 -1926777362 -1023949417  2064180460  -559198979
+[415]  1326612378 -1041956781  -440895112  -866362087 -1278619130   172850383
+[421] -1405979452  -384207627  1766332722   288732939   962208464 -1547538287
+[427]  1929150750  1742727943  2017824668  1738206189 -1057557046   101192899
+[433]  1380550440   669401865  -405527754 -1914703809  -339372684  1799590373
+[439]  -446073502 -2050295429  1806698112   852079745 -1640949682  1138388087
+[445]  -639506868  -656193827  2138437626   118048051  1612906712 -1008032519
+[451]  1916780646  2050506671  -101326300 -2004489515   184475026 -1662396437
+[457]  1596184112  -675089295 -1577550978  -843167257 -1257707268  1425235405
+[463] -1066236374  1924108707  1386210952   793281257   245344662  2064476959
+[469] -1555146028   456097733 -1370795582 -1220980133  -193949216   124596321
+[475] -1371166034 -1037925545 -1180330068 -1443221315    42967130  -125699565
+[481] -1814349768 -1063330599   759619270 -1177128305   656015236 -1588637515
+[487] -2075012622  -283088693 -1961805424  1984391249 -1077172770 -1822549817
+[493]  -496831908  1105641389  1026573962 -1178108285  1689253352 -2041793847
+[499]   591945718  1305105919  -412889036   750017957  1389714978 -2000282821
+[505] -1321153216   143694913  -805475058  -645395913   615250188   308808349
+[511]   276265146 -1182327053 -1934024808   913376441  1517759782 -1411377809
+[517]   418827492  1391306389   542701138  1645308331  -738571024 -1035482063
+[523]    84803646 -1032366169   548121532 -1930620531  -179816726  1283971939
+[529]   173126984   518705833 -2124003754   382644447  1935537556   491400069
+[535]  1679792770  1655264283  -285689696 -1221855199  -504340626 -2117926633
+[541]  -783480212 -1901800323  1833271578 -1991199789 -1030441224   358161561
+[547] -1150768250   252520527  -521909692  -120001419   908872370  -336274805
+[553]  1018630224   -88334319  1985448606 -1061026169  1010504988  1350456173
+[559]   852645706 -1205295037   828187816  1729815177  -795779914 -1026393153
+[565]   781503220 -1503073947  2135033570  1226505467  -428846080 -1875426303
+[571] -1900641842   244017143   568380364  1462275677  1762769274 -1021921101
+[577]   424017496  -917560199  1572035046  2115349295 -1137018972   713630293
+[583]   686018322   520272747 -1273003088  1520198641  -465550082  1341531495
+[589] -1385615748  1662158157  -874076246 -1511922397   866796552  1221911145
+[595]    73507606   445494943   744509524 -1115121851  1297392450  -598534693
+[601] -1132486816   212500449  1290261550   798572247   616512812  1617639485
+[607]  -537648678  -569299565  -526060104   978000985 -1695598522  1873911311
+[613]   340874500 -1149876171  1737982834   695405643   353085200   417372113
+[619]  -346017954 -1916029881 -1735526436  1461823277   580724746  -622095869
+[625]  -686746776   705745481
+
+##com.oracle.truffle.r.test.rng.TestRRNG.testDirectSeedAssignment#Output.IgnoreWarningContext#
+#.Random.seed <- c(401, 1, 2); invisible(runif(3))
+Warning message:
+In runif(3) :
+  '.Random.seed' is not an integer vector but of type 'double', so ignored
+
+##com.oracle.truffle.r.test.rng.TestRRNG.testDirectSeedAssignment#
+#.Random.seed <- c(401L, 1L, 2L); runif(3)
+[1] 0.5641106 0.2932388 0.6696743
+
+##com.oracle.truffle.r.test.rng.TestRRNG.testDirectSeedAssignment#Output.IgnoreWarningContext#
+#.Random.seed <- c(999, 1, 2); invisible(runif(3))
+Warning message:
+In runif(3) :
+  '.Random.seed' is not an integer vector but of type 'double', so ignored
+
+##com.oracle.truffle.r.test.rng.TestRRNG.testGeneratorChange#
+#RNGkind('Marsaglia-Multicarry'); RNGkind('Mersenne-Twister'); set.seed(2); runif(5);
+[1] 0.1848823 0.7023740 0.5733263 0.1680519 0.9438393
+
+##com.oracle.truffle.r.test.rng.TestRRNG.testGeneratorChange#
+#invisible(runif(5)); RNGkind('Marsaglia-Multicarry'); set.seed(2); runif(5);
+[1] 0.8431527 0.5749091 0.1531976 0.3460321 0.2313936
+
 ##com.oracle.truffle.r.test.rpackages.TestRecommendedPackages.testLoad#Ignored.OutputFormatting#Context.NonShared#Context.LongTimeout#
 #{ library(KernSmooth, lib.loc = "tmptest/com.oracle.truffle.r.test.rpackages"); detach("package:KernSmooth"); }
 KernSmooth 2.23 loaded
diff --git a/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/rng/TestRRNG.java b/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/rng/TestRRNG.java
new file mode 100644
index 0000000000000000000000000000000000000000..b578868551d8e969ee14175f6d268f234077b164
--- /dev/null
+++ b/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/rng/TestRRNG.java
@@ -0,0 +1,51 @@
+/*
+ * 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.rng;
+
+import org.junit.Test;
+
+import com.oracle.truffle.r.test.TestBase;
+
+public class TestRRNG extends TestBase {
+    @Test
+    public void testDirectSeedAssignment() {
+        // changes generator to MarsagliaMulticarry and sets its 2 seeds
+        assertEval(".Random.seed <- c(401L, 1L, 2L); runif(3)");
+        // wrong values: not integer
+        assertEval(Output.IgnoreWarningContext, ".Random.seed <- c(401, 1, 2); invisible(runif(3))");
+        // wrong values: wrong generator number
+        assertEval(Output.IgnoreWarningContext, ".Random.seed <- c(999, 1, 2); invisible(runif(3))");
+    }
+
+    @Test
+    public void testGeneratorChange() {
+        assertEval("invisible(runif(5)); RNGkind('Marsaglia-Multicarry'); set.seed(2); runif(5);");
+        assertEval("RNGkind('Marsaglia-Multicarry'); RNGkind('Mersenne-Twister'); set.seed(2); runif(5);");
+    }
+
+    @Test
+    public void testDirectReadingSeed() {
+        assertEval("invisible(runif(1)); length(.Random.seed)");
+        assertEval("set.seed(42); .Random.seed");
+    }
+}
diff --git a/mx.fastr/copyrights/overrides b/mx.fastr/copyrights/overrides
index b3fe4a42434be4ae36cad844009248ce24d0d24e..d76934e4506834d6521c3efa1b2386f4a4ef143a 100644
--- a/mx.fastr/copyrights/overrides
+++ b/mx.fastr/copyrights/overrides
@@ -210,6 +210,7 @@ com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/rng/mm/MarsagliaMu
 com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/rng/mt/MersenneTwister.java,hiroshima.copyright
 com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/rng/RNGInitAdapter.java,gnu_r.copyright
 com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/rng/RRNG.java,gnu_r.copyright
+com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/rng/RandomNumberGenerator.java,gnu_r.copyright
 com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/PrimitiveMethodsInfo.java,gnu_r_gentleman_ihaka.copyright
 com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/ROptions.java,gnu_r.copyright
 com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/RRuntime.java,gnu_r.copyright
diff --git a/mx.fastr/mx_fastr.py b/mx.fastr/mx_fastr.py
index 21b21917982e13eb40112575b6414fe38c9a2d4e..8b88672dec8e4eabbae35236a26d532e6f0a01c5 100644
--- a/mx.fastr/mx_fastr.py
+++ b/mx.fastr/mx_fastr.py
@@ -391,7 +391,7 @@ def _test_subpackage(name):
     return '.'.join((_test_package(), name))
 
 def _simple_unit_tests():
-    return ','.join(map(_test_subpackage, ['library.base', 'library.stats', 'library.utils', 'library.fastr', 'builtins', 'functions', 'tck', 'parser', 'S4']))
+    return ','.join(map(_test_subpackage, ['library.base', 'library.stats', 'library.utils', 'library.fastr', 'builtins', 'functions', 'tck', 'parser', 'S4', 'rng']))
 
 def _package_unit_tests():
     return ','.join(map(_test_subpackage, ['rffi', 'rpackages']))
diff --git a/mx.fastr/mx_fastr_pkgs.py b/mx.fastr/mx_fastr_pkgs.py
index 25bb29517c7e5affbf052eb4790a71b5df0c4033..874dbf5e651d0f7df036a77780e047dc0dff5cec 100644
--- a/mx.fastr/mx_fastr_pkgs.py
+++ b/mx.fastr/mx_fastr_pkgs.py
@@ -235,11 +235,27 @@ def pkgtest(args):
     return rc
 
 def tar_tests(testdir):
-    test_tar = join(_fastr_suite_dir, testdir + '.tar')
-    subprocess.call(['tar', 'cf', test_tar, os.path.basename(testdir)])
-    if os.path.exists(test_tar + '.gz'):
-        os.remove(test_tar + '.gz')
-    subprocess.call(['gzip', test_tar])
+    if os.environ.has_key('FASTR_TEST_GZIP'):
+        test_tar = testdir + '.tar'
+        subprocess.call(['tar', 'cf', test_tar, os.path.basename(testdir)])
+        if os.path.exists(test_tar + '.gz'):
+            os.remove(test_tar + '.gz')
+        subprocess.call(['gzip', test_tar])
+    else:
+        # workaround for lack of support for accessing gz files
+        with open(testdir + '.agg', 'w') as o:
+            for root, _, files in os.walk(testdir):
+                for f in files:
+                    ext = os.path.splitext(f)[1]
+                    if f == 'test_time' or f == 'testfile_status' or ext == '.pdf' or ext == '.prev' or ext == '.save':
+                        continue
+                    absfile = join(root, f)
+                    relfile = relpath(absfile, _fastr_suite_dir())
+                    o.write('#### ' + relfile + '\n')
+                    with open(absfile) as inp:
+                        text = inp.read()
+                        o.write(text)
+
 
 class TestFileStatus:
     '''