From 49e5ba8c2927a135e02b494bba249bb24e5ba039 Mon Sep 17 00:00:00 2001
From: stepan <stepan.sindelar@oracle.com>
Date: Tue, 3 Jan 2017 15:28:33 +0100
Subject: [PATCH] Stats vs nmath structure refactoring + wilcox externals

- code corresponding to 'nmath' in GnuR moved to new package:
com.oracle.truffle.r.runtime.nmath
- it turns that Wilcox uses Choose, which is a builtin node, the original
structure did not allow code reuse in such cases
- implement wilcox externals {d/p/q}wilcox and wilcox_free + improved choose
---
 .../oracle/truffle/r/library/stats/Cdist.java |   4 +-
 .../{RMultinom.java => RMultinomNode.java}    |  96 +----
 ...Functions.java => RandFunctionsNodes.java} |  84 +---
 .../truffle/r/library/stats/Random2.java      |  89 -----
 .../truffle/r/library/stats/Signrank.java     |  52 ---
 ...unctions.java => StatsFunctionsNodes.java} |  95 ++---
 .../truffle/r/library/stats/Wilcox.java       |  77 ----
 .../r/library/stats/WilcoxFreeNode.java       |  35 ++
 .../builtin/base/BaseGammaFunctions.java      |  20 +-
 .../r/nodes/builtin/base/BasePackage.java     |   4 +-
 .../base/{Choose.java => ChooseBuiltin.java}  |  30 +-
 .../foreign/CallAndExternalFunctions.java     | 319 ++++++++--------
 .../builtin/base/foreign/LookupAdapter.java   |   6 +-
 .../com/oracle/truffle/r/runtime/RError.java  |   3 +-
 .../truffle/r/runtime/RErrorHandling.java     |   2 +-
 .../truffle/r/runtime/nmath}/Arithmetic.java  |   6 +-
 .../truffle/r/runtime/nmath/Choose.java       | 138 +++++++
 .../oracle/truffle/r/runtime/nmath}/DPQ.java  |  15 +-
 .../r/runtime/nmath}/GammaFunctions.java      |  73 ++--
 .../truffle/r/runtime/nmath}/LBeta.java       |  14 +-
 .../oracle/truffle/r/runtime/nmath/Mach.java  |  21 +-
 .../r/runtime/nmath}/MathConstants.java       |   4 +-
 .../r/runtime/nmath/MathFunctions.java        |  78 ++++
 .../truffle/r/runtime/nmath}/RMath.java       |  15 +-
 .../truffle/r/runtime/nmath}/RMathError.java  |   2 +-
 .../r/runtime/nmath/RandomFunctions.java      |  91 +++++
 .../truffle/r/runtime/nmath}/TOMS708.java     |  14 +-
 .../r/runtime/nmath/distr}/Cauchy.java        |  25 +-
 .../truffle/r/runtime/nmath/distr}/Chisq.java |  19 +-
 .../truffle/r/runtime/nmath/distr}/DBeta.java |  10 +-
 .../truffle/r/runtime/nmath/distr/DGamma.java |  33 ++
 .../r/runtime/nmath/distr}/DHyper.java        |  19 +-
 .../r/runtime/nmath/distr}/DNBeta.java        |   8 +-
 .../r/runtime/nmath/distr}/DNBinom.java       |  22 +-
 .../r/runtime/nmath/distr}/DNChisq.java       |  10 +-
 .../truffle/r/runtime/nmath/distr}/DNorm.java |  16 +-
 .../truffle/r/runtime/nmath/distr}/DPois.java |  24 +-
 .../r/runtime/nmath/distr}/Dbinom.java        |  10 +-
 .../truffle/r/runtime/nmath/distr}/Df.java    |  15 +-
 .../truffle/r/runtime/nmath/distr}/Dnf.java   |  11 +-
 .../truffle/r/runtime/nmath/distr}/Dt.java    |  16 +-
 .../truffle/r/runtime/nmath/distr}/Exp.java   |  17 +-
 .../truffle/r/runtime/nmath/distr}/Geom.java  |  19 +-
 .../r/runtime/nmath/distr}/LogNormal.java     |  17 +-
 .../truffle/r/runtime/nmath/distr}/Logis.java |  20 +-
 .../r/runtime/nmath/distr}/PGamma.java        |  10 +-
 .../r/runtime/nmath/distr}/PHyper.java        |  11 +-
 .../r/runtime/nmath/distr}/PNBeta.java        |  17 +-
 .../r/runtime/nmath/distr}/PNBinom.java       |  10 +-
 .../r/runtime/nmath/distr}/PNChisq.java       |  31 +-
 .../truffle/r/runtime/nmath/distr}/PPois.java |  10 +-
 .../truffle/r/runtime/nmath/distr}/Pbeta.java |   9 +-
 .../r/runtime/nmath/distr}/Pbinom.java        |  10 +-
 .../truffle/r/runtime/nmath/distr}/Pf.java    |  13 +-
 .../truffle/r/runtime/nmath/distr}/Pnf.java   |  10 +-
 .../truffle/r/runtime/nmath/distr}/Pnorm.java |   7 +-
 .../truffle/r/runtime/nmath/distr}/Pt.java    |  18 +-
 .../truffle/r/runtime/nmath/distr}/QBeta.java |  36 +-
 .../truffle/r/runtime/nmath/distr/QGamma.java |  33 ++
 .../r/runtime/nmath/distr}/QHyper.java        |  20 +-
 .../r/runtime/nmath/distr}/QNBeta.java        |  15 +-
 .../r/runtime/nmath/distr}/QNBinom.java       |  15 +-
 .../r/runtime/nmath/distr}/QNChisq.java       |  21 +-
 .../truffle/r/runtime/nmath/distr}/QPois.java |  13 +-
 .../r/runtime/nmath/distr}/Qbinom.java        |  10 +-
 .../truffle/r/runtime/nmath/distr}/Qf.java    |  15 +-
 .../truffle/r/runtime/nmath/distr}/Qnf.java   |  10 +-
 .../truffle/r/runtime/nmath/distr}/Qnorm.java |  33 +-
 .../truffle/r/runtime/nmath/distr}/Qt.java    |  31 +-
 .../runtime/nmath/distr}/QuantileSearch.java  |   4 +-
 .../truffle/r/runtime/nmath/distr}/RBeta.java |  15 +-
 .../r/runtime/nmath/distr}/RGamma.java        |  12 +-
 .../r/runtime/nmath/distr}/RHyper.java        |  13 +-
 .../r/runtime/nmath/distr/RMultinom.java      | 100 +++++
 .../r/runtime/nmath/distr}/RNBinom.java       |  11 +-
 .../r/runtime/nmath/distr}/RNchisq.java       |   9 +-
 .../truffle/r/runtime/nmath/distr}/RPois.java |  13 +-
 .../r/runtime/nmath/distr}/Rbinom.java        |  10 +-
 .../truffle/r/runtime/nmath/distr}/Rf.java    |   9 +-
 .../truffle/r/runtime/nmath/distr}/Rnorm.java |   9 +-
 .../truffle/r/runtime/nmath/distr}/Rt.java    |  14 +-
 .../truffle/r/runtime/nmath/distr}/SExp.java  |   7 +-
 .../truffle/r/runtime/nmath/distr}/SNorm.java |   9 +-
 .../r/runtime/nmath/distr/Signrank.java       |  87 +++++
 .../truffle/r/runtime/nmath/distr}/Unif.java  |  16 +-
 .../r/runtime/nmath/distr}/Weibull.java       |  15 +-
 .../truffle/r/runtime/nmath/distr/Wilcox.java | 360 ++++++++++++++++++
 .../truffle/r/test/ExpectedTestOutput.test    | 225 ++++++++++-
 .../test/library/stats/TestDistributions.java |   6 +-
 mx.fastr/copyrights/overrides                 | 141 +++----
 90 files changed, 2068 insertions(+), 1123 deletions(-)
 rename com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/stats/{RMultinom.java => RMultinomNode.java} (58%)
 rename com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/stats/{RandGenerationFunctions.java => RandFunctionsNodes.java} (81%)
 delete mode 100644 com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/stats/Random2.java
 delete mode 100644 com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/stats/Signrank.java
 rename com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/stats/{StatsFunctions.java => StatsFunctionsNodes.java} (89%)
 delete mode 100644 com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/stats/Wilcox.java
 create mode 100644 com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/stats/WilcoxFreeNode.java
 rename com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/{Choose.java => ChooseBuiltin.java} (87%)
 rename {com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/stats => com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/nmath}/Arithmetic.java (95%)
 create mode 100644 com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/nmath/Choose.java
 rename {com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/stats => com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/nmath}/DPQ.java (91%)
 rename {com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/stats => com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/nmath}/GammaFunctions.java (95%)
 rename {com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/stats => com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/nmath}/LBeta.java (81%)
 rename com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/stats/MathInit.java => com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/nmath/Mach.java (82%)
 rename {com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/stats => com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/nmath}/MathConstants.java (97%)
 create mode 100644 com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/nmath/MathFunctions.java
 rename {com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/stats => com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/nmath}/RMath.java (96%)
 rename {com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/stats => com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/nmath}/RMathError.java (98%)
 create mode 100644 com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/nmath/RandomFunctions.java
 rename {com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/stats => com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/nmath}/TOMS708.java (99%)
 rename {com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/stats => com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/nmath/distr}/Cauchy.java (87%)
 rename {com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/stats => com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/nmath/distr}/Chisq.java (70%)
 rename {com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/stats => com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/nmath/distr}/DBeta.java (89%)
 create mode 100644 com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/nmath/distr/DGamma.java
 rename {com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/stats => com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/nmath/distr}/DHyper.java (72%)
 rename {com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/stats => com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/nmath/distr}/DNBeta.java (91%)
 rename {com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/stats => com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/nmath/distr}/DNBinom.java (84%)
 rename {com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/stats => com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/nmath/distr}/DNChisq.java (90%)
 rename {com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/stats => com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/nmath/distr}/DNorm.java (71%)
 rename {com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/stats => com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/nmath/distr}/DPois.java (69%)
 rename {com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/stats => com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/nmath/distr}/Dbinom.java (87%)
 rename {com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/stats => com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/nmath/distr}/Df.java (78%)
 rename {com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/stats => com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/nmath/distr}/Dnf.java (87%)
 rename {com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/stats => com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/nmath/distr}/Dt.java (82%)
 rename {com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/stats => com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/nmath/distr}/Exp.java (81%)
 rename {com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/stats => com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/nmath/distr}/Geom.java (85%)
 rename {com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/stats => com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/nmath/distr}/LogNormal.java (83%)
 rename {com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/stats => com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/nmath/distr}/Logis.java (86%)
 rename {com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/stats => com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/nmath/distr}/PGamma.java (75%)
 rename {com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/stats => com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/nmath/distr}/PHyper.java (87%)
 rename {com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/stats => com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/nmath/distr}/PNBeta.java (87%)
 rename {com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/stats => com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/nmath/distr}/PNBinom.java (90%)
 rename {com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/stats => com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/nmath/distr}/PNChisq.java (91%)
 rename {com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/stats => com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/nmath/distr}/PPois.java (73%)
 rename {com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/stats => com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/nmath/distr}/Pbeta.java (90%)
 rename {com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/stats => com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/nmath/distr}/Pbinom.java (80%)
 rename {com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/stats => com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/nmath/distr}/Pf.java (81%)
 rename {com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/stats => com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/nmath/distr}/Pnf.java (82%)
 rename {com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/stats => com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/nmath/distr}/Pnorm.java (97%)
 rename {com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/stats => com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/nmath/distr}/Pt.java (78%)
 rename {com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/stats => com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/nmath/distr}/QBeta.java (96%)
 create mode 100644 com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/nmath/distr/QGamma.java
 rename {com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/stats => com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/nmath/distr}/QHyper.java (81%)
 rename {com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/stats => com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/nmath/distr}/QNBeta.java (79%)
 rename {com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/stats => com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/nmath/distr}/QNBinom.java (88%)
 rename {com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/stats => com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/nmath/distr}/QNChisq.java (84%)
 rename {com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/stats => com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/nmath/distr}/QPois.java (85%)
 rename {com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/stats => com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/nmath/distr}/Qbinom.java (91%)
 rename {com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/stats => com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/nmath/distr}/Qf.java (79%)
 rename {com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/stats => com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/nmath/distr}/Qnf.java (79%)
 rename {com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/stats => com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/nmath/distr}/Qnorm.java (85%)
 rename {com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/stats => com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/nmath/distr}/Qt.java (89%)
 rename {com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/stats => com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/nmath/distr}/QuantileSearch.java (97%)
 rename {com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/stats => com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/nmath/distr}/RBeta.java (89%)
 rename {com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/stats => com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/nmath/distr}/RGamma.java (93%)
 rename {com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/stats => com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/nmath/distr}/RHyper.java (96%)
 create mode 100644 com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/nmath/distr/RMultinom.java
 rename {com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/stats => com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/nmath/distr}/RNBinom.java (82%)
 rename {com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/stats => com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/nmath/distr}/RNchisq.java (76%)
 rename {com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/stats => com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/nmath/distr}/RPois.java (95%)
 rename {com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/stats => com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/nmath/distr}/Rbinom.java (96%)
 rename {com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/stats => com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/nmath/distr}/Rf.java (71%)
 rename {com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/stats => com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/nmath/distr}/Rnorm.java (81%)
 rename {com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/stats => com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/nmath/distr}/Rt.java (57%)
 rename {com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/stats => com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/nmath/distr}/SExp.java (89%)
 rename {com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/stats => com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/nmath/distr}/SNorm.java (78%)
 create mode 100644 com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/nmath/distr/Signrank.java
 rename {com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/stats => com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/nmath/distr}/Unif.java (86%)
 rename {com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/stats => com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/nmath/distr}/Weibull.java (85%)
 create mode 100644 com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/nmath/distr/Wilcox.java

diff --git a/com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/stats/Cdist.java b/com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/stats/Cdist.java
index 907b465efc..b736f81e92 100644
--- a/com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/stats/Cdist.java
+++ b/com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/stats/Cdist.java
@@ -6,14 +6,14 @@
  * Copyright (c) 1995, 1996, 1997  Robert Gentleman and Ross Ihaka
  * Copyright (c) 1995-2014, The R Core Team
  * Copyright (c) 2002-2008, The R Foundation
- * Copyright (c) 2016, Oracle and/or its affiliates
+ * Copyright (c) 2016, 2017, 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_MIN;
 import static com.oracle.truffle.r.nodes.builtin.CastBuilder.Predef.instanceOf;
+import static com.oracle.truffle.r.runtime.nmath.MathConstants.DBL_MIN;
 
 import com.oracle.truffle.api.dsl.Cached;
 import com.oracle.truffle.api.dsl.Specialization;
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/RMultinomNode.java
similarity index 58%
rename from com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/stats/RMultinom.java
rename to com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/stats/RMultinomNode.java
index 9a0f80cd9a..3aa1c3b601 100644
--- a/com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/stats/RMultinom.java
+++ b/com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/stats/RMultinomNode.java
@@ -6,7 +6,7 @@
  * 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
+ * Copyright (c) 2016, 2017, Oracle and/or its affiliates
  *
  * All rights reserved.
  */
@@ -18,15 +18,10 @@ 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.builtin.CastBuilder;
@@ -35,17 +30,25 @@ import com.oracle.truffle.r.nodes.function.opt.ReuseNonSharedNode;
 import com.oracle.truffle.r.nodes.function.opt.UpdateShareableChildValueNode;
 import com.oracle.truffle.r.runtime.RError;
 import com.oracle.truffle.r.runtime.RError.Message;
-import com.oracle.truffle.r.runtime.RRuntime;
 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.nmath.RandomFunctions.RandomNumberProvider;
+import com.oracle.truffle.r.runtime.nmath.distr.RMultinom;
+import com.oracle.truffle.r.runtime.nmath.distr.Rbinom;
 import com.oracle.truffle.r.runtime.rng.RRNG;
 
-public abstract class RMultinom extends RExternalBuiltinNode.Arg3 {
-
+/**
+ * Implements the vectorization of {@link RMultinom}.
+ */
+public abstract class RMultinomNode extends RExternalBuiltinNode.Arg3 {
     private final Rbinom rbinom = new Rbinom();
 
+    public static RMultinomNode create() {
+        return RMultinomNodeGen.create();
+    }
+
     @Override
     protected void createCasts(CastBuilder casts) {
         casts.arg(0).asIntegerVector().findFirst().mustBe(notIntNA(), SHOW_CALLER, Message.INVALID_FIRST_ARGUMENT_NAME, "n");
@@ -71,7 +74,7 @@ public abstract class RMultinom extends RExternalBuiltinNode.Arg3 {
         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);
+            isComplete &= RMultinom.rmultinom(size, probs, k, result, ik, rand, rbinom);
         }
         RRNG.putRNGState();
 
@@ -108,77 +111,4 @@ public abstract class RMultinom extends RExternalBuiltinNode.Arg3 {
             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 nIn, double[] prob, int maxK, int[] rN, int rnStartIdx, RandomNumberProvider rand) {
-        BigDecimal pTot = BigDecimal.ZERO;
-        /*
-         * This calculation is sensitive to exact values, so we try to ensure that the calculations
-         * are as accurate as possible so different platforms are more likely to give the same
-         * result.
-         */
-
-        int n = nIn;
-        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 (int k = 0; k < maxK; k++) {
-            double pp = prob[k];
-            if (!Double.isFinite(pp) || pp < 0. || pp > 1.) {
-                rN[rnStartIdx + k] = RRuntime.INT_NA;
-                return false;
-            }
-            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 (int k = 0; k < maxK - 1; k++) { /* (p_tot, n) are for "remaining binomial" */
-            BigDecimal probK = new BigDecimal(prob[k]);
-            if (probK.compareTo(BigDecimal.ZERO) != 0) {
-                double pp = probK.divide(pTot, RoundingMode.HALF_UP).doubleValue();
-                // System.out.printf("[%d] %.17f\n", k + 1, pp);
-                rN[rnStartIdx + k] = ((pp < 1.) ? (int) rbinom.execute(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/RandGenerationFunctions.java b/com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/stats/RandFunctionsNodes.java
similarity index 81%
rename from com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/stats/RandGenerationFunctions.java
rename to com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/stats/RandFunctionsNodes.java
index 61aae8184e..2620717f91 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/RandFunctionsNodes.java
@@ -6,7 +6,7 @@
  * Copyright (c) 1995, 1996, 1997  Robert Gentleman and Ross Ihaka
  * Copyright (c) 1998-2013, The R Core Team
  * Copyright (c) 2003-2015, The R Foundation
- * Copyright (c) 2016, 2016, Oracle and/or its affiliates
+ * Copyright (c) 2016, 2017, Oracle and/or its affiliates
  *
  * All rights reserved.
  */
@@ -26,10 +26,10 @@ import com.oracle.truffle.api.dsl.TypeSystemReference;
 import com.oracle.truffle.api.nodes.Node;
 import com.oracle.truffle.api.profiles.BranchProfile;
 import com.oracle.truffle.api.profiles.LoopConditionProfile;
-import com.oracle.truffle.r.library.stats.RandGenerationFunctionsFactory.ConvertToLengthNodeGen;
-import com.oracle.truffle.r.library.stats.RandGenerationFunctionsFactory.RandFunction1NodeGen;
-import com.oracle.truffle.r.library.stats.RandGenerationFunctionsFactory.RandFunction2NodeGen;
-import com.oracle.truffle.r.library.stats.RandGenerationFunctionsFactory.RandFunction3NodeGen;
+import com.oracle.truffle.r.library.stats.RandFunctionsNodesFactory.ConvertToLengthNodeGen;
+import com.oracle.truffle.r.library.stats.RandFunctionsNodesFactory.RandFunction1NodeGen;
+import com.oracle.truffle.r.library.stats.RandFunctionsNodesFactory.RandFunction2NodeGen;
+import com.oracle.truffle.r.library.stats.RandFunctionsNodesFactory.RandFunction3NodeGen;
 import com.oracle.truffle.r.nodes.EmptyTypeSystemFlatLayout;
 import com.oracle.truffle.r.nodes.builtin.CastBuilder;
 import com.oracle.truffle.r.nodes.builtin.RExternalBuiltinNode;
@@ -43,77 +43,27 @@ import com.oracle.truffle.r.runtime.data.RDouble;
 import com.oracle.truffle.r.runtime.data.model.RAbstractDoubleVector;
 import com.oracle.truffle.r.runtime.data.model.RAbstractIntVector;
 import com.oracle.truffle.r.runtime.data.model.RAbstractVector;
+import com.oracle.truffle.r.runtime.nmath.RandomFunctions.RandFunction1_Double;
+import com.oracle.truffle.r.runtime.nmath.RandomFunctions.RandFunction2_Double;
+import com.oracle.truffle.r.runtime.nmath.RandomFunctions.RandFunction3_Double;
+import com.oracle.truffle.r.runtime.nmath.RandomFunctions.RandomNumberProvider;
 import com.oracle.truffle.r.runtime.nodes.RNode;
 import com.oracle.truffle.r.runtime.rng.RRNG;
-import com.oracle.truffle.r.runtime.rng.RRNG.NormKind;
-import com.oracle.truffle.r.runtime.rng.RandomNumberGenerator;
 
 /**
  * Contains infrastructure for R external functions implementing generation of a random value from
  * given random value distribution. To implement such external function, implement one of:
  * {@link RandFunction3_Double}, {@link RandFunction2_Double} or {@link RandFunction1_Double}.
  */
-public final class RandGenerationFunctions {
+public final class RandFunctionsNodes {
     @CompilationFinal private static final RDouble DUMMY_VECTOR = RDouble.valueOf(1);
 
-    private RandGenerationFunctions() {
+    private RandFunctionsNodes() {
         // static class
     }
 
-    public static final class RandomNumberProvider {
-        final RandomNumberGenerator generator;
-        final NormKind normKind;
-
-        public RandomNumberProvider(RandomNumberGenerator generator, NormKind normKind) {
-            this.generator = generator;
-            this.normKind = normKind;
-        }
-
-        public static RandomNumberProvider fromCurrentRNG() {
-            return new RandomNumberProvider(RRNG.currentGenerator(), RRNG.currentNormKind());
-        }
-
-        protected boolean isSame(RandomNumberProvider other) {
-            return this.generator == other.generator && this.normKind == other.normKind;
-        }
-
-        public double unifRand() {
-            return generator.genrandDouble();
-        }
-
-        public double normRand() {
-            return SNorm.normRand(generator, normKind);
-        }
-
-        public double expRand() {
-            return SExp.expRand(generator);
-        }
-    }
-
     // inspired by the DEFRAND{X}_REAL and DEFRAND{X}_INT macros in GnuR
 
-    public abstract static class RandFunction3_Double extends Node {
-        public abstract double execute(double a, double b, double c, RandomNumberProvider rand);
-    }
-
-    public abstract static class RandFunction2_Double extends RandFunction3_Double {
-        public abstract double execute(double a, double b, RandomNumberProvider rand);
-
-        @Override
-        public final double execute(double a, double b, double c, RandomNumberProvider rand) {
-            return execute(a, b, rand);
-        }
-    }
-
-    public abstract static class RandFunction1_Double extends RandFunction2_Double {
-        public abstract double execute(double a, RandomNumberProvider rand);
-
-        @Override
-        public final double execute(double a, double b, RandomNumberProvider rand) {
-            return execute(a, rand);
-        }
-    }
-
     /**
      * Converts given value to actual length that should be used as length of the output vector. The
      * argument must be cast using {@link #addLengthCast(CastBuilder)}. Using this node allows us to
@@ -304,13 +254,13 @@ public final class RandGenerationFunctions {
         }
 
         public static RandFunction3Node createInt(RandFunction3_Double function) {
-            return RandFunction3NodeGen.create(RandGenerationFunctionsFactory.RandFunctionIntExecutorNodeGen.create(function));
+            return RandFunction3NodeGen.create(RandFunctionsNodesFactory.RandFunctionIntExecutorNodeGen.create(function));
         }
 
         // Note: for completeness of the API
         @SuppressWarnings("unused")
         public static RandFunction3Node createDouble(RandFunction3_Double function) {
-            return RandFunction3NodeGen.create(RandGenerationFunctionsFactory.RandFunctionDoubleExecutorNodeGen.create(function));
+            return RandFunction3NodeGen.create(RandFunctionsNodesFactory.RandFunctionDoubleExecutorNodeGen.create(function));
         }
 
         @Override
@@ -336,11 +286,11 @@ public final class RandGenerationFunctions {
         }
 
         public static RandFunction2Node createInt(RandFunction2_Double function) {
-            return RandFunction2NodeGen.create(RandGenerationFunctionsFactory.RandFunctionIntExecutorNodeGen.create(function));
+            return RandFunction2NodeGen.create(RandFunctionsNodesFactory.RandFunctionIntExecutorNodeGen.create(function));
         }
 
         public static RandFunction2Node createDouble(RandFunction2_Double function) {
-            return RandFunction2NodeGen.create(RandGenerationFunctionsFactory.RandFunctionDoubleExecutorNodeGen.create(function));
+            return RandFunction2NodeGen.create(RandFunctionsNodesFactory.RandFunctionDoubleExecutorNodeGen.create(function));
         }
 
         @Override
@@ -365,11 +315,11 @@ public final class RandGenerationFunctions {
         }
 
         public static RandFunction1Node createInt(RandFunction1_Double function) {
-            return RandFunction1NodeGen.create(RandGenerationFunctionsFactory.RandFunctionIntExecutorNodeGen.create(function));
+            return RandFunction1NodeGen.create(RandFunctionsNodesFactory.RandFunctionIntExecutorNodeGen.create(function));
         }
 
         public static RandFunction1Node createDouble(RandFunction1_Double function) {
-            return RandFunction1NodeGen.create(RandGenerationFunctionsFactory.RandFunctionDoubleExecutorNodeGen.create(function));
+            return RandFunction1NodeGen.create(RandFunctionsNodesFactory.RandFunctionDoubleExecutorNodeGen.create(function));
         }
 
         @Override
diff --git a/com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/stats/Random2.java b/com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/stats/Random2.java
deleted file mode 100644
index de77422aef..0000000000
--- a/com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/stats/Random2.java
+++ /dev/null
@@ -1,89 +0,0 @@
-/*
- * This material is distributed under the GNU General Public License
- * Version 2. You may review the terms of this license at
- * http://www.gnu.org/licenses/gpl-2.0.html
- *
- * Copyright (c) 1995-2012, The R Core Team
- * Copyright (c) 2003, The R Foundation
- * Copyright (c) 2013, 2016, Oracle and/or its affiliates
- *
- * All rights reserved.
- */
-package com.oracle.truffle.r.library.stats;
-
-import static com.oracle.truffle.r.library.stats.DPQ.rdtciv;
-import static com.oracle.truffle.r.library.stats.DPQ.rdtqiv;
-
-/*
- * Logic derived from GNU-R, see inline comments.
- */
-public final class Random2 {
-    private Random2() {
-        // only static members
-    }
-
-    // from GNUR: qnorm.c
-    public static double qnorm5(double p, double mu, double sigma, boolean lowerTail, boolean logP) {
-        // R_Q_P01_boundaries(p, ML_NEGINF, ML_POSINF);
-
-        // if(sigma < 0) { ML_ERR_return_NAN; }
-        if (sigma == 0) {
-            return mu;
-        }
-
-        double pU = rdtqiv(p, lowerTail, logP); /* real lower_tail prob. p */
-        double q = pU - 0.5;
-
-        double val;
-        if (Math.abs(q) <= .425) { /* 0.075 <= p <= 0.925 */
-            double r = .180625 - q * q;
-            val = q *
-                            (((((((r * 2509.0809287301226727 + 33430.575583588128105) * r + 67265.770927008700853) * r + 45921.953931549871457) * r + 13731.693765509461125) * r +
-                                            1971.5909503065514427) *
-                                            r + 133.14166789178437745) *
-                                            r + 3.387132872796366608) /
-                            (((((((r * 5226.495278852854561 + 28729.085735721942674) * r + 39307.89580009271061) * r + 21213.794301586595867) * r + 5394.1960214247511077) * r + 687.1870074920579083) *
-                                            r + 42.313330701600911252) *
-                                            r + 1.);
-        } else { /* closer than 0.075 from {0,1} boundary */
-
-            /* r = min(p, 1-p) < 0.075 */
-            double r;
-            if (q > 0) {
-                r = rdtciv(p, lowerTail, logP); /* 1-p */
-            } else {
-                r = pU; /* = R_DT_Iv(p) ^= p */
-            }
-            r = Math.sqrt(-((logP && ((lowerTail && q <= 0) || (!lowerTail && q > 0))) ? p : /* else */Math.log(r)));
-            /* r = sqrt(-log(r)) <==> min(p, 1-p) = exp( - r^2 ) */
-
-            if (r <= 5.) { /* <==> min(p,1-p) >= exp(-25) ~= 1.3888e-11 */
-                r += -1.6;
-                val = (((((((r * 7.7454501427834140764e-4 + .0227238449892691845833) * r + .24178072517745061177) * r + 1.27045825245236838258) * r + 3.64784832476320460504) * r +
-                                5.7694972214606914055) *
-                                r + 4.6303378461565452959) *
-                                r + 1.42343711074968357734) /
-                                (((((((r * 1.05075007164441684324e-9 + 5.475938084995344946e-4) * r + .0151986665636164571966) * r + .14810397642748007459) * r + .68976733498510000455) * r +
-                                                1.6763848301838038494) *
-                                                r + 2.05319162663775882187) *
-                                                r + 1.);
-            } else { /* very close to 0 or 1 */
-                r += -5.;
-                val = (((((((r * 2.01033439929228813265e-7 + 2.71155556874348757815e-5) * r + .0012426609473880784386) * r + .026532189526576123093) * r + .29656057182850489123) * r +
-                                1.7848265399172913358) *
-                                r + 5.4637849111641143699) *
-                                r + 6.6579046435011037772) /
-                                (((((((r * 2.04426310338993978564e-15 + 1.4215117583164458887e-7) * r + 1.8463183175100546818e-5) * r + 7.868691311456132591e-4) * r + .0148753612908506148525) * r +
-                                                .13692988092273580531) *
-                                                r + .59983220655588793769) *
-                                                r + 1.);
-            }
-
-            if (q < 0.0) {
-                val = -val;
-            }
-            /* return (q >= 0.)? r : -r ; */
-        }
-        return mu + sigma * val;
-    }
-}
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
deleted file mode 100644
index 662ca85255..0000000000
--- a/com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/stats/Signrank.java
+++ /dev/null
@@ -1,52 +0,0 @@
-/*
- * This material is distributed under the GNU General Public License
- * Version 2. You may review the terms of this license at
- * http://www.gnu.org/licenses/gpl-2.0.html
- *
- * Copyright (c) 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.RMath.forceint;
-
-import com.oracle.truffle.r.library.stats.RandGenerationFunctions.RandFunction1_Double;
-import com.oracle.truffle.r.library.stats.RandGenerationFunctions.RandomNumberProvider;
-
-public final class Signrank {
-    private Signrank() {
-        // only static members
-    }
-
-    public static final class RSignrank extends RandFunction1_Double {
-        @Override
-        public double execute(double nIn, RandomNumberProvider rand) {
-            if (Double.isNaN(nIn)) {
-                return nIn;
-            }
-            if (Double.isInfinite(nIn)) {
-                // In GnuR these "results" seem to be generated due to the behaviour of R_forceint,
-                // and the "(int) n" cast, which ends up casting +/-infinity to integer...
-                return nIn < 0 ? RMathError.defaultError() : 0;
-            }
-
-            double n = forceint(nIn);
-            if (n < 0) {
-                return RMathError.defaultError();
-            }
-
-            if (n == 0) {
-                return 0;
-            }
-            double r = 0.0;
-            int k = (int) n;
-            for (int i = 0; i < k; i++) {
-                r += (i + 1) * Math.floor(rand.unifRand() + 0.5);
-            }
-            return r;
-        }
-    }
-}
diff --git a/com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/stats/StatsFunctions.java b/com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/stats/StatsFunctionsNodes.java
similarity index 89%
rename from com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/stats/StatsFunctions.java
rename to com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/stats/StatsFunctionsNodes.java
index 9d5484b763..73325ec93f 100644
--- a/com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/stats/StatsFunctions.java
+++ b/com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/stats/StatsFunctionsNodes.java
@@ -6,7 +6,7 @@
  * Copyright (c) 1995, 1996, 1997  Robert Gentleman and Ross Ihaka
  * Copyright (c) 1998-2013, The R Core Team
  * Copyright (c) 2003-2015, The R Foundation
- * Copyright (c) 2016, 2016, Oracle and/or its affiliates
+ * Copyright (c) 2016, 2017, Oracle and/or its affiliates
  *
  * All rights reserved.
  */
@@ -21,8 +21,14 @@ import com.oracle.truffle.api.nodes.Node;
 import com.oracle.truffle.api.profiles.BranchProfile;
 import com.oracle.truffle.api.profiles.ConditionProfile;
 import com.oracle.truffle.api.profiles.LoopConditionProfile;
-import com.oracle.truffle.r.library.stats.StatsFunctionsFactory.Function4_1NodeGen;
-import com.oracle.truffle.r.library.stats.StatsFunctionsFactory.Function4_2NodeGen;
+import com.oracle.truffle.r.library.stats.StatsFunctionsNodesFactory.ApproxNodeGen;
+import com.oracle.truffle.r.library.stats.StatsFunctionsNodesFactory.ApproxTestNodeGen;
+import com.oracle.truffle.r.library.stats.StatsFunctionsNodesFactory.Function2_1NodeGen;
+import com.oracle.truffle.r.library.stats.StatsFunctionsNodesFactory.Function2_2NodeGen;
+import com.oracle.truffle.r.library.stats.StatsFunctionsNodesFactory.Function3_1NodeGen;
+import com.oracle.truffle.r.library.stats.StatsFunctionsNodesFactory.Function3_2NodeGen;
+import com.oracle.truffle.r.library.stats.StatsFunctionsNodesFactory.Function4_1NodeGen;
+import com.oracle.truffle.r.library.stats.StatsFunctionsNodesFactory.Function4_2NodeGen;
 import com.oracle.truffle.r.nodes.attributes.UnaryCopyAttributesNode;
 import com.oracle.truffle.r.nodes.builtin.CastBuilder;
 import com.oracle.truffle.r.nodes.builtin.RExternalBuiltinNode;
@@ -34,67 +40,24 @@ import com.oracle.truffle.r.runtime.data.RDouble;
 import com.oracle.truffle.r.runtime.data.RDoubleVector;
 import com.oracle.truffle.r.runtime.data.RNull;
 import com.oracle.truffle.r.runtime.data.model.RAbstractDoubleVector;
+import com.oracle.truffle.r.runtime.nmath.MathFunctions.Function2_1;
+import com.oracle.truffle.r.runtime.nmath.MathFunctions.Function2_2;
+import com.oracle.truffle.r.runtime.nmath.MathFunctions.Function3_1;
+import com.oracle.truffle.r.runtime.nmath.MathFunctions.Function3_2;
+import com.oracle.truffle.r.runtime.nmath.MathFunctions.Function4_1;
+import com.oracle.truffle.r.runtime.nmath.MathFunctions.Function4_2;
 import com.oracle.truffle.r.runtime.nodes.RNode;
 import com.oracle.truffle.r.runtime.ops.na.NACheck;
 
 // inspired by arithmetic.c
 
-public final class StatsFunctions {
+public final class StatsFunctionsNodes {
     @CompilationFinal private static final RDouble DUMMY_VECTOR = RDouble.valueOf(1);
 
-    private StatsFunctions() {
+    private StatsFunctionsNodes() {
         // private
     }
 
-    public interface Function4_2 {
-        double evaluate(double a, double b, double c, double d, boolean x, boolean y);
-    }
-
-    public interface Function4_1 extends Function4_2 {
-        @Override
-        default double evaluate(double a, double b, double c, double d, boolean x, boolean y) {
-            return evaluate(a, b, c, d, x);
-        }
-
-        double evaluate(double a, double b, double c, double d, boolean x);
-    }
-
-    public interface Function3_2 extends Function4_2 {
-        @Override
-        default double evaluate(double a, double b, double c, double d, boolean x, boolean y) {
-            return evaluate(a, b, c, x, y);
-        }
-
-        double evaluate(double a, double b, double c, boolean x, boolean y);
-    }
-
-    public interface Function3_1 extends Function3_2 {
-        @Override
-        default double evaluate(double a, double b, double c, boolean x, boolean y) {
-            return evaluate(a, b, c, x);
-        }
-
-        double evaluate(double a, double b, double c, boolean x);
-    }
-
-    public interface Function2_1 extends Function3_2 {
-        @Override
-        default double evaluate(double a, double b, double c, boolean x, boolean y) {
-            return evaluate(a, b, x);
-        }
-
-        double evaluate(double a, double b, boolean x);
-    }
-
-    public interface Function2_2 extends Function3_2 {
-        @Override
-        default double evaluate(double a, double b, double c, boolean x, boolean y) {
-            return evaluate(a, b, x, y);
-        }
-
-        double evaluate(double a, double b, boolean x, boolean y);
-    }
-
     static final class StatFunctionProfiles {
         final BranchProfile nan = BranchProfile.create();
         final NACheck aCheck = NACheck.create();
@@ -182,6 +145,10 @@ public final class StatsFunctions {
             this.function = function;
         }
 
+        public static Function3_2Node create(Function3_2 function) {
+            return Function3_2NodeGen.create(function);
+        }
+
         @Override
         protected void createCasts(CastBuilder casts) {
             casts.arg(0).asDoubleVector();
@@ -263,6 +230,10 @@ public final class StatsFunctions {
             this.function = function;
         }
 
+        public static Function3_1Node create(Function3_1 function) {
+            return Function3_1NodeGen.create(function);
+        }
+
         @Override
         protected void createCasts(CastBuilder casts) {
             casts.arg(0).asDoubleVector();
@@ -286,6 +257,10 @@ public final class StatsFunctions {
             this.function = function;
         }
 
+        public static Function2_1Node create(Function2_1 function) {
+            return Function2_1NodeGen.create(function);
+        }
+
         @Override
         protected void createCasts(CastBuilder casts) {
             casts.arg(0).asDoubleVector();
@@ -308,6 +283,10 @@ public final class StatsFunctions {
             this.function = function;
         }
 
+        public static Function2_2Node create(Function2_2 function) {
+            return Function2_2NodeGen.create(function);
+        }
+
         @Override
         protected void createCasts(CastBuilder casts) {
             casts.arg(0).asDoubleVector();
@@ -325,6 +304,10 @@ public final class StatsFunctions {
     }
 
     public abstract static class ApproxTest extends RExternalBuiltinNode.Arg4 {
+        public static ApproxTest create() {
+            return ApproxTestNodeGen.create();
+        }
+
         @Override
         protected void createCasts(CastBuilder casts) {
             casts.arg(2).asIntegerVector().findFirst();
@@ -359,6 +342,10 @@ public final class StatsFunctions {
     public abstract static class Approx extends RExternalBuiltinNode.Arg7 {
         private static final NACheck naCheck = NACheck.create();
 
+        public static Approx create() {
+            return ApproxNodeGen.create();
+        }
+
         @Override
         protected void createCasts(CastBuilder casts) {
             casts.arg(2).asDoubleVector();
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
deleted file mode 100644
index 7f36653c93..0000000000
--- a/com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/stats/Wilcox.java
+++ /dev/null
@@ -1,77 +0,0 @@
-/*
- * This material is distributed under the GNU General Public License
- * Version 2. You may review the terms of this license at
- * http://www.gnu.org/licenses/gpl-2.0.html
- *
- * Copyright (c) 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 {
-    private Wilcox() {
-        // only static members
-    }
-
-    public static final class RWilcox extends RandFunction2_Double {
-        @Override
-        public double execute(double mIn, double nIn, RandomNumberProvider rand) {
-            int i;
-            int j;
-            int k;
-            double r;
-
-            /* NaNs propagated correctly */
-            if (Double.isNaN(mIn) || Double.isNaN(nIn)) {
-                return mIn + nIn;
-            }
-            if (!Double.isFinite(mIn) || !Double.isFinite(nIn)) {
-                // GnuR does not check this and tries to allocate the memory, we do check this, but
-                // fail with the same error message for compatibility reasons.
-                throw RError.error(RError.SHOW_CALLER, CALLOC_COULD_NOT_ALLOCATE_INF);
-            }
-
-            double m = RMath.round(mIn);
-            double n = RMath.round(nIn);
-            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.library/src/com/oracle/truffle/r/library/stats/WilcoxFreeNode.java b/com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/stats/WilcoxFreeNode.java
new file mode 100644
index 0000000000..5b9f40f4ae
--- /dev/null
+++ b/com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/stats/WilcoxFreeNode.java
@@ -0,0 +1,35 @@
+/*
+ * Copyright (c) 2017, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact 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.library.stats;
+
+import com.oracle.truffle.r.nodes.builtin.RExternalBuiltinNode;
+import com.oracle.truffle.r.runtime.data.RNull;
+import com.oracle.truffle.r.runtime.nmath.distr.Wilcox.WilcoxData;
+
+public final class WilcoxFreeNode extends RExternalBuiltinNode.Arg0 {
+    @Override
+    public Object execute() {
+        WilcoxData.freeData();
+        return RNull.instance;
+    }
+}
diff --git a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/BaseGammaFunctions.java b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/BaseGammaFunctions.java
index 6ddf11b6b0..40a318d36f 100644
--- a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/BaseGammaFunctions.java
+++ b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/BaseGammaFunctions.java
@@ -6,24 +6,24 @@
  * Copyright (C) 1998 Ross Ihaka
  * Copyright (c) 1998--2012, The R Core Team
  * Copyright (c) 2004, The R Foundation
- * Copyright (c) 2013, 2016, Oracle and/or its affiliates
+ * Copyright (c) 2013, 2017, Oracle and/or its affiliates
  *
  * All rights reserved.
  */
 package com.oracle.truffle.r.nodes.builtin.base;
 
-import static com.oracle.truffle.r.library.stats.MathConstants.DBL_EPSILON;
-import static com.oracle.truffle.r.library.stats.MathConstants.DBL_MANT_DIG;
-import static com.oracle.truffle.r.library.stats.MathConstants.DBL_MAX_EXP;
-import static com.oracle.truffle.r.library.stats.MathConstants.DBL_MIN_EXP;
-import static com.oracle.truffle.r.library.stats.MathConstants.M_LOG10_2;
-import static com.oracle.truffle.r.library.stats.MathConstants.M_PI;
-import static com.oracle.truffle.r.library.stats.RMath.fmax2;
 import static com.oracle.truffle.r.nodes.builtin.CastBuilder.Predef.complexValue;
 import static com.oracle.truffle.r.nodes.builtin.CastBuilder.Predef.numericValue;
 import static com.oracle.truffle.r.runtime.RDispatch.MATH_GROUP_GENERIC;
 import static com.oracle.truffle.r.runtime.builtins.RBehavior.PURE;
 import static com.oracle.truffle.r.runtime.builtins.RBuiltinKind.PRIMITIVE;
+import static com.oracle.truffle.r.runtime.nmath.MathConstants.DBL_EPSILON;
+import static com.oracle.truffle.r.runtime.nmath.MathConstants.DBL_MANT_DIG;
+import static com.oracle.truffle.r.runtime.nmath.MathConstants.DBL_MAX_EXP;
+import static com.oracle.truffle.r.runtime.nmath.MathConstants.DBL_MIN_EXP;
+import static com.oracle.truffle.r.runtime.nmath.MathConstants.M_LOG10_2;
+import static com.oracle.truffle.r.runtime.nmath.MathConstants.M_PI;
+import static com.oracle.truffle.r.runtime.nmath.RMath.fmax2;
 
 import com.oracle.truffle.api.CompilerDirectives;
 import com.oracle.truffle.api.CompilerDirectives.CompilationFinal;
@@ -31,8 +31,6 @@ import com.oracle.truffle.api.CompilerDirectives.TruffleBoundary;
 import com.oracle.truffle.api.dsl.NodeChild;
 import com.oracle.truffle.api.dsl.NodeChildren;
 import com.oracle.truffle.api.dsl.Specialization;
-import com.oracle.truffle.r.library.stats.GammaFunctions;
-import com.oracle.truffle.r.library.stats.RMath;
 import com.oracle.truffle.r.nodes.builtin.CastBuilder;
 import com.oracle.truffle.r.nodes.builtin.RBuiltinNode;
 import com.oracle.truffle.r.nodes.builtin.base.BaseGammaFunctionsFactory.DpsiFnCalcNodeGen;
@@ -45,6 +43,8 @@ import com.oracle.truffle.r.runtime.data.closures.RClosures;
 import com.oracle.truffle.r.runtime.data.model.RAbstractDoubleVector;
 import com.oracle.truffle.r.runtime.data.model.RAbstractIntVector;
 import com.oracle.truffle.r.runtime.data.model.RAbstractLogicalVector;
+import com.oracle.truffle.r.runtime.nmath.GammaFunctions;
+import com.oracle.truffle.r.runtime.nmath.RMath;
 import com.oracle.truffle.r.runtime.nodes.RNode;
 import com.oracle.truffle.r.runtime.ops.na.NACheck;
 
diff --git a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/BasePackage.java b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/BasePackage.java
index 3e4ab57a47..2373dd7173 100644
--- a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/BasePackage.java
+++ b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/BasePackage.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2013, 2016, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2013, 2017, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -200,7 +200,7 @@ public class BasePackage extends RBuiltinPackage {
         add(BaseGammaFunctions.Gamma.class, BaseGammaFunctionsFactory.GammaNodeGen::create);
         add(BaseGammaFunctions.Lgamma.class, BaseGammaFunctionsFactory.LgammaNodeGen::create);
         add(BaseGammaFunctions.TriGamma.class, BaseGammaFunctionsFactory.TriGammaNodeGen::create);
-        add(Choose.class, ChooseNodeGen::create);
+        add(ChooseBuiltin.class, ChooseBuiltinNodeGen::create);
         add(Bincode.class, BincodeNodeGen::create);
         add(Bind.CbindInternal.class, BindNodeGen.CbindInternalNodeGen::create);
         add(Bind.RbindInternal.class, BindNodeGen.RbindInternalNodeGen::create);
diff --git a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/Choose.java b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/ChooseBuiltin.java
similarity index 87%
rename from com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/Choose.java
rename to com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/ChooseBuiltin.java
index 8550d93fb7..7a63eaf5b9 100644
--- a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/Choose.java
+++ b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/ChooseBuiltin.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2016, 2017, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -42,13 +42,14 @@ import com.oracle.truffle.r.runtime.builtins.RBuiltin;
 import com.oracle.truffle.r.runtime.data.RDataFactory;
 import com.oracle.truffle.r.runtime.data.model.RAbstractDoubleVector;
 import com.oracle.truffle.r.runtime.data.model.RAbstractIntVector;
+import com.oracle.truffle.r.runtime.nmath.Choose;
 import com.oracle.truffle.r.runtime.ops.na.NACheck;
 
 /**
  * Binomial coefficients (n, k) for real n and integral k (rounded with warning).
  */
 @RBuiltin(name = "choose", kind = INTERNAL, parameterNames = {"n", "k"}, behavior = PURE)
-public abstract class Choose extends RBuiltinNode {
+public abstract class ChooseBuiltin extends RBuiltinNode {
 
     private final NACheck na = NACheck.create();
 
@@ -111,29 +112,10 @@ public abstract class Choose extends RBuiltinNode {
         return RDataFactory.createDoubleVector(result, na.neverSeenNA());
     }
 
-    private static double choose(double n, int ka) {
-        int k = ka;
-        if (n == RRuntime.DOUBLE_NA || k == RRuntime.INT_NA) {
+    public static double choose(double n, int k) {
+        if (RRuntime.isNA(n) || RRuntime.isNA(k)) {
             return RRuntime.DOUBLE_NA;
         }
-
-        // symmetry: this e.g. turns (n=3,k=3) into (n=3,k=0)
-        int intN = (int) n;
-        if (n == intN && intN - k < k && intN >= 0) {
-            k = intN - k;
-        }
-
-        if (k < 0) {
-            return 0;
-        } else if (k == 0) {
-            return 1;
-        }
-
-        // TODO: if n is too large (GnuR: > 30) use 'lchoose' and converts its result
-        double result = n;
-        for (int i = 2; i <= k; i++) {
-            result *= (n - i + 1) / i;
-        }
-        return result;
+        return Choose.choose(n, k);
     }
 }
diff --git a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/foreign/CallAndExternalFunctions.java b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/foreign/CallAndExternalFunctions.java
index 179a8b5a97..26cbf2838b 100644
--- a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/foreign/CallAndExternalFunctions.java
+++ b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/foreign/CallAndExternalFunctions.java
@@ -40,100 +40,20 @@ import com.oracle.truffle.r.library.methods.SlotFactory.R_getSlotNodeGen;
 import com.oracle.truffle.r.library.methods.SlotFactory.R_setSlotNodeGen;
 import com.oracle.truffle.r.library.methods.SubstituteDirectNodeGen;
 import com.oracle.truffle.r.library.parallel.ParallelFunctionsFactory.MCIsChildNodeGen;
-import com.oracle.truffle.r.library.stats.Cauchy;
-import com.oracle.truffle.r.library.stats.Cauchy.DCauchy;
-import com.oracle.truffle.r.library.stats.Cauchy.PCauchy;
-import com.oracle.truffle.r.library.stats.Cauchy.RCauchy;
 import com.oracle.truffle.r.library.stats.CdistNodeGen;
-import com.oracle.truffle.r.library.stats.Chisq;
-import com.oracle.truffle.r.library.stats.Chisq.RChisq;
 import com.oracle.truffle.r.library.stats.CompleteCases;
 import com.oracle.truffle.r.library.stats.CovcorNodeGen;
 import com.oracle.truffle.r.library.stats.CutreeNodeGen;
-import com.oracle.truffle.r.library.stats.DBeta;
-import com.oracle.truffle.r.library.stats.DHyper;
-import com.oracle.truffle.r.library.stats.DNBeta;
-import com.oracle.truffle.r.library.stats.DNBinom.DNBinomFunc;
-import com.oracle.truffle.r.library.stats.DNBinom.DNBinomMu;
-import com.oracle.truffle.r.library.stats.DNChisq;
-import com.oracle.truffle.r.library.stats.DNorm;
-import com.oracle.truffle.r.library.stats.DPois;
-import com.oracle.truffle.r.library.stats.Dbinom;
-import com.oracle.truffle.r.library.stats.Df;
-import com.oracle.truffle.r.library.stats.Dnf;
 import com.oracle.truffle.r.library.stats.DoubleCentreNodeGen;
-import com.oracle.truffle.r.library.stats.Dt;
-import com.oracle.truffle.r.library.stats.Exp.DExp;
-import com.oracle.truffle.r.library.stats.Exp.PExp;
-import com.oracle.truffle.r.library.stats.Exp.QExp;
-import com.oracle.truffle.r.library.stats.Exp.RExp;
-import com.oracle.truffle.r.library.stats.GammaFunctions.DGamma;
-import com.oracle.truffle.r.library.stats.GammaFunctions.QgammaFunc;
-import com.oracle.truffle.r.library.stats.Geom;
-import com.oracle.truffle.r.library.stats.Geom.DGeom;
-import com.oracle.truffle.r.library.stats.Geom.RGeom;
-import com.oracle.truffle.r.library.stats.LogNormal;
-import com.oracle.truffle.r.library.stats.LogNormal.DLNorm;
-import com.oracle.truffle.r.library.stats.LogNormal.PLNorm;
-import com.oracle.truffle.r.library.stats.LogNormal.QLNorm;
-import com.oracle.truffle.r.library.stats.Logis;
-import com.oracle.truffle.r.library.stats.Logis.DLogis;
-import com.oracle.truffle.r.library.stats.Logis.RLogis;
-import com.oracle.truffle.r.library.stats.PGamma;
-import com.oracle.truffle.r.library.stats.PHyper;
-import com.oracle.truffle.r.library.stats.PNBeta;
-import com.oracle.truffle.r.library.stats.PNBinom.PNBinomFunc;
-import com.oracle.truffle.r.library.stats.PNBinom.PNBinomMu;
-import com.oracle.truffle.r.library.stats.PNChisq;
-import com.oracle.truffle.r.library.stats.PPois;
-import com.oracle.truffle.r.library.stats.Pbeta;
-import com.oracle.truffle.r.library.stats.Pbinom;
-import com.oracle.truffle.r.library.stats.Pf;
-import com.oracle.truffle.r.library.stats.Pnf;
-import com.oracle.truffle.r.library.stats.Pnorm;
-import com.oracle.truffle.r.library.stats.Pt;
-import com.oracle.truffle.r.library.stats.QBeta;
-import com.oracle.truffle.r.library.stats.QHyper;
-import com.oracle.truffle.r.library.stats.QNBeta;
-import com.oracle.truffle.r.library.stats.QNBinom.QNBinomFunc;
-import com.oracle.truffle.r.library.stats.QNBinom.QNBinomMu;
-import com.oracle.truffle.r.library.stats.QNChisq;
-import com.oracle.truffle.r.library.stats.QPois;
-import com.oracle.truffle.r.library.stats.Qbinom;
-import com.oracle.truffle.r.library.stats.Qf;
-import com.oracle.truffle.r.library.stats.Qnf;
-import com.oracle.truffle.r.library.stats.Qnorm;
-import com.oracle.truffle.r.library.stats.Qt;
-import com.oracle.truffle.r.library.stats.RBeta;
-import com.oracle.truffle.r.library.stats.RGamma;
-import com.oracle.truffle.r.library.stats.RHyper;
-import com.oracle.truffle.r.library.stats.RMultinomNodeGen;
-import com.oracle.truffle.r.library.stats.RNBinom.RNBinomFunc;
-import com.oracle.truffle.r.library.stats.RNBinom.RNBinomMu;
-import com.oracle.truffle.r.library.stats.RNchisq;
-import com.oracle.truffle.r.library.stats.RPois;
-import com.oracle.truffle.r.library.stats.RandGenerationFunctions;
-import com.oracle.truffle.r.library.stats.RandGenerationFunctions.RandFunction1Node;
-import com.oracle.truffle.r.library.stats.RandGenerationFunctions.RandFunction2Node;
-import com.oracle.truffle.r.library.stats.RandGenerationFunctions.RandFunction3Node;
-import com.oracle.truffle.r.library.stats.Rbinom;
-import com.oracle.truffle.r.library.stats.Rf;
-import com.oracle.truffle.r.library.stats.Rnorm;
-import com.oracle.truffle.r.library.stats.Rt;
-import com.oracle.truffle.r.library.stats.Signrank.RSignrank;
+import com.oracle.truffle.r.library.stats.RMultinomNode;
+import com.oracle.truffle.r.library.stats.RandFunctionsNodes;
+import com.oracle.truffle.r.library.stats.RandFunctionsNodes.RandFunction1Node;
+import com.oracle.truffle.r.library.stats.RandFunctionsNodes.RandFunction2Node;
+import com.oracle.truffle.r.library.stats.RandFunctionsNodes.RandFunction3Node;
 import com.oracle.truffle.r.library.stats.SplineFunctionsFactory.SplineCoefNodeGen;
 import com.oracle.truffle.r.library.stats.SplineFunctionsFactory.SplineEvalNodeGen;
-import com.oracle.truffle.r.library.stats.StatsFunctions;
-import com.oracle.truffle.r.library.stats.StatsFunctionsFactory;
-import com.oracle.truffle.r.library.stats.Unif.DUnif;
-import com.oracle.truffle.r.library.stats.Unif.PUnif;
-import com.oracle.truffle.r.library.stats.Unif.QUnif;
-import com.oracle.truffle.r.library.stats.Unif.Runif;
-import com.oracle.truffle.r.library.stats.Weibull.DWeibull;
-import com.oracle.truffle.r.library.stats.Weibull.PWeibull;
-import com.oracle.truffle.r.library.stats.Weibull.QWeibull;
-import com.oracle.truffle.r.library.stats.Weibull.RWeibull;
-import com.oracle.truffle.r.library.stats.Wilcox.RWilcox;
+import com.oracle.truffle.r.library.stats.StatsFunctionsNodes;
+import com.oracle.truffle.r.library.stats.WilcoxFreeNode;
 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;
@@ -165,6 +85,89 @@ import com.oracle.truffle.r.runtime.ffi.CallRFFI;
 import com.oracle.truffle.r.runtime.ffi.DLL;
 import com.oracle.truffle.r.runtime.ffi.NativeCallInfo;
 import com.oracle.truffle.r.runtime.ffi.RFFIFactory;
+import com.oracle.truffle.r.runtime.nmath.distr.Cauchy;
+import com.oracle.truffle.r.runtime.nmath.distr.Cauchy.DCauchy;
+import com.oracle.truffle.r.runtime.nmath.distr.Cauchy.PCauchy;
+import com.oracle.truffle.r.runtime.nmath.distr.Cauchy.RCauchy;
+import com.oracle.truffle.r.runtime.nmath.distr.Chisq;
+import com.oracle.truffle.r.runtime.nmath.distr.Chisq.RChisq;
+import com.oracle.truffle.r.runtime.nmath.distr.DBeta;
+import com.oracle.truffle.r.runtime.nmath.distr.DGamma;
+import com.oracle.truffle.r.runtime.nmath.distr.DHyper;
+import com.oracle.truffle.r.runtime.nmath.distr.DNBeta;
+import com.oracle.truffle.r.runtime.nmath.distr.DNBinom.DNBinomFunc;
+import com.oracle.truffle.r.runtime.nmath.distr.DNBinom.DNBinomMu;
+import com.oracle.truffle.r.runtime.nmath.distr.DNChisq;
+import com.oracle.truffle.r.runtime.nmath.distr.DNorm;
+import com.oracle.truffle.r.runtime.nmath.distr.DPois;
+import com.oracle.truffle.r.runtime.nmath.distr.Dbinom;
+import com.oracle.truffle.r.runtime.nmath.distr.Df;
+import com.oracle.truffle.r.runtime.nmath.distr.Dnf;
+import com.oracle.truffle.r.runtime.nmath.distr.Dt;
+import com.oracle.truffle.r.runtime.nmath.distr.Exp.DExp;
+import com.oracle.truffle.r.runtime.nmath.distr.Exp.PExp;
+import com.oracle.truffle.r.runtime.nmath.distr.Exp.QExp;
+import com.oracle.truffle.r.runtime.nmath.distr.Exp.RExp;
+import com.oracle.truffle.r.runtime.nmath.distr.Geom;
+import com.oracle.truffle.r.runtime.nmath.distr.Geom.DGeom;
+import com.oracle.truffle.r.runtime.nmath.distr.Geom.RGeom;
+import com.oracle.truffle.r.runtime.nmath.distr.LogNormal;
+import com.oracle.truffle.r.runtime.nmath.distr.LogNormal.DLNorm;
+import com.oracle.truffle.r.runtime.nmath.distr.LogNormal.PLNorm;
+import com.oracle.truffle.r.runtime.nmath.distr.LogNormal.QLNorm;
+import com.oracle.truffle.r.runtime.nmath.distr.Logis;
+import com.oracle.truffle.r.runtime.nmath.distr.Logis.DLogis;
+import com.oracle.truffle.r.runtime.nmath.distr.Logis.RLogis;
+import com.oracle.truffle.r.runtime.nmath.distr.PGamma;
+import com.oracle.truffle.r.runtime.nmath.distr.PHyper;
+import com.oracle.truffle.r.runtime.nmath.distr.PNBeta;
+import com.oracle.truffle.r.runtime.nmath.distr.PNBinom.PNBinomFunc;
+import com.oracle.truffle.r.runtime.nmath.distr.PNBinom.PNBinomMu;
+import com.oracle.truffle.r.runtime.nmath.distr.PNChisq;
+import com.oracle.truffle.r.runtime.nmath.distr.PPois;
+import com.oracle.truffle.r.runtime.nmath.distr.Pbeta;
+import com.oracle.truffle.r.runtime.nmath.distr.Pbinom;
+import com.oracle.truffle.r.runtime.nmath.distr.Pf;
+import com.oracle.truffle.r.runtime.nmath.distr.Pnf;
+import com.oracle.truffle.r.runtime.nmath.distr.Pnorm;
+import com.oracle.truffle.r.runtime.nmath.distr.Pt;
+import com.oracle.truffle.r.runtime.nmath.distr.QBeta;
+import com.oracle.truffle.r.runtime.nmath.distr.QGamma;
+import com.oracle.truffle.r.runtime.nmath.distr.QHyper;
+import com.oracle.truffle.r.runtime.nmath.distr.QNBeta;
+import com.oracle.truffle.r.runtime.nmath.distr.QNBinom.QNBinomFunc;
+import com.oracle.truffle.r.runtime.nmath.distr.QNBinom.QNBinomMu;
+import com.oracle.truffle.r.runtime.nmath.distr.QNChisq;
+import com.oracle.truffle.r.runtime.nmath.distr.QPois;
+import com.oracle.truffle.r.runtime.nmath.distr.Qbinom;
+import com.oracle.truffle.r.runtime.nmath.distr.Qf;
+import com.oracle.truffle.r.runtime.nmath.distr.Qnf;
+import com.oracle.truffle.r.runtime.nmath.distr.Qnorm;
+import com.oracle.truffle.r.runtime.nmath.distr.Qt;
+import com.oracle.truffle.r.runtime.nmath.distr.RBeta;
+import com.oracle.truffle.r.runtime.nmath.distr.RGamma;
+import com.oracle.truffle.r.runtime.nmath.distr.RHyper;
+import com.oracle.truffle.r.runtime.nmath.distr.RNBinom.RNBinomFunc;
+import com.oracle.truffle.r.runtime.nmath.distr.RNBinom.RNBinomMu;
+import com.oracle.truffle.r.runtime.nmath.distr.RNchisq;
+import com.oracle.truffle.r.runtime.nmath.distr.RPois;
+import com.oracle.truffle.r.runtime.nmath.distr.Rbinom;
+import com.oracle.truffle.r.runtime.nmath.distr.Rf;
+import com.oracle.truffle.r.runtime.nmath.distr.Rnorm;
+import com.oracle.truffle.r.runtime.nmath.distr.Rt;
+import com.oracle.truffle.r.runtime.nmath.distr.Signrank.RSignrank;
+import com.oracle.truffle.r.runtime.nmath.distr.Unif.DUnif;
+import com.oracle.truffle.r.runtime.nmath.distr.Unif.PUnif;
+import com.oracle.truffle.r.runtime.nmath.distr.Unif.QUnif;
+import com.oracle.truffle.r.runtime.nmath.distr.Unif.Runif;
+import com.oracle.truffle.r.runtime.nmath.distr.Weibull.DWeibull;
+import com.oracle.truffle.r.runtime.nmath.distr.Weibull.PWeibull;
+import com.oracle.truffle.r.runtime.nmath.distr.Weibull.QWeibull;
+import com.oracle.truffle.r.runtime.nmath.distr.Weibull.RWeibull;
+import com.oracle.truffle.r.runtime.nmath.distr.Wilcox.DWilcox;
+import com.oracle.truffle.r.runtime.nmath.distr.Wilcox.PWilcox;
+import com.oracle.truffle.r.runtime.nmath.distr.Wilcox.QWilcox;
+import com.oracle.truffle.r.runtime.nmath.distr.Wilcox.RWilcox;
 
 /**
  * {@code .Call}, {@code .Call.graphics}, {@code .External}, {@code .External2},
@@ -283,9 +286,9 @@ public class CallAndExternalFunctions {
                 case "SplineEval":
                     return SplineEvalNodeGen.create();
                 case "pnorm":
-                    return StatsFunctionsFactory.Function3_2NodeGen.create(new Pnorm());
+                    return StatsFunctionsNodes.Function3_2Node.create(new Pnorm());
                 case "qnorm":
-                    return StatsFunctionsFactory.Function3_2NodeGen.create(new Qnorm());
+                    return StatsFunctionsNodes.Function3_2Node.create(new Qnorm());
                 case "rnorm":
                     return RandFunction2Node.createDouble(new Rnorm());
                 case "runif":
@@ -325,135 +328,141 @@ public class CallAndExternalFunctions {
                 case "rhyper":
                     return RandFunction3Node.createInt(new RHyper());
                 case "phyper":
-                    return StatsFunctions.Function4_2Node.create(new PHyper());
+                    return StatsFunctionsNodes.Function4_2Node.create(new PHyper());
                 case "dhyper":
-                    return StatsFunctions.Function4_1Node.create(new DHyper());
+                    return StatsFunctionsNodes.Function4_1Node.create(new DHyper());
                 case "qhyper":
-                    return StatsFunctions.Function4_2Node.create(new QHyper());
+                    return StatsFunctionsNodes.Function4_2Node.create(new QHyper());
                 case "pnchisq":
-                    return StatsFunctionsFactory.Function3_2NodeGen.create(new PNChisq());
+                    return StatsFunctionsNodes.Function3_2Node.create(new PNChisq());
                 case "qnchisq":
-                    return StatsFunctionsFactory.Function3_2NodeGen.create(new QNChisq());
+                    return StatsFunctionsNodes.Function3_2Node.create(new QNChisq());
                 case "dnchisq":
-                    return StatsFunctionsFactory.Function3_1NodeGen.create(new DNChisq());
+                    return StatsFunctionsNodes.Function3_1Node.create(new DNChisq());
                 case "qt":
-                    return StatsFunctionsFactory.Function2_2NodeGen.create(new Qt());
+                    return StatsFunctionsNodes.Function2_2Node.create(new Qt());
                 case "pt":
-                    return StatsFunctionsFactory.Function2_2NodeGen.create(new Pt());
+                    return StatsFunctionsNodes.Function2_2Node.create(new Pt());
                 case "qgamma":
-                    return StatsFunctionsFactory.Function3_2NodeGen.create(new QgammaFunc());
+                    return StatsFunctionsNodes.Function3_2Node.create(new QGamma());
                 case "dbinom":
-                    return StatsFunctionsFactory.Function3_1NodeGen.create(new Dbinom());
+                    return StatsFunctionsNodes.Function3_1Node.create(new Dbinom());
                 case "qbinom":
-                    return StatsFunctionsFactory.Function3_2NodeGen.create(new Qbinom());
+                    return StatsFunctionsNodes.Function3_2Node.create(new Qbinom());
                 case "punif":
-                    return StatsFunctionsFactory.Function3_2NodeGen.create(new PUnif());
+                    return StatsFunctionsNodes.Function3_2Node.create(new PUnif());
                 case "dunif":
-                    return StatsFunctionsFactory.Function3_1NodeGen.create(new DUnif());
+                    return StatsFunctionsNodes.Function3_1Node.create(new DUnif());
                 case "qunif":
-                    return StatsFunctionsFactory.Function3_2NodeGen.create(new QUnif());
+                    return StatsFunctionsNodes.Function3_2Node.create(new QUnif());
                 case "ppois":
-                    return StatsFunctionsFactory.Function2_2NodeGen.create(new PPois());
+                    return StatsFunctionsNodes.Function2_2Node.create(new PPois());
                 case "qpois":
-                    return StatsFunctionsFactory.Function2_2NodeGen.create(new QPois());
+                    return StatsFunctionsNodes.Function2_2Node.create(new QPois());
                 case "qweibull":
-                    return StatsFunctionsFactory.Function3_2NodeGen.create(new QWeibull());
+                    return StatsFunctionsNodes.Function3_2Node.create(new QWeibull());
                 case "pweibull":
-                    return StatsFunctionsFactory.Function3_2NodeGen.create(new PWeibull());
+                    return StatsFunctionsNodes.Function3_2Node.create(new PWeibull());
                 case "dweibull":
-                    return StatsFunctionsFactory.Function3_1NodeGen.create(new DWeibull());
+                    return StatsFunctionsNodes.Function3_1Node.create(new DWeibull());
                 case "rbinom":
                     return RandFunction2Node.createInt(new Rbinom());
                 case "pbinom":
-                    return StatsFunctionsFactory.Function3_2NodeGen.create(new Pbinom());
+                    return StatsFunctionsNodes.Function3_2Node.create(new Pbinom());
                 case "pbeta":
-                    return StatsFunctionsFactory.Function3_2NodeGen.create(new Pbeta());
+                    return StatsFunctionsNodes.Function3_2Node.create(new Pbeta());
                 case "qbeta":
-                    return StatsFunctionsFactory.Function3_2NodeGen.create(new QBeta());
+                    return StatsFunctionsNodes.Function3_2Node.create(new QBeta());
                 case "dcauchy":
-                    return StatsFunctionsFactory.Function3_1NodeGen.create(new DCauchy());
+                    return StatsFunctionsNodes.Function3_1Node.create(new DCauchy());
                 case "pcauchy":
-                    return StatsFunctionsFactory.Function3_2NodeGen.create(new PCauchy());
+                    return StatsFunctionsNodes.Function3_2Node.create(new PCauchy());
                 case "qcauchy":
-                    return StatsFunctionsFactory.Function3_2NodeGen.create(new Cauchy.QCauchy());
+                    return StatsFunctionsNodes.Function3_2Node.create(new Cauchy.QCauchy());
                 case "pf":
-                    return StatsFunctionsFactory.Function3_2NodeGen.create(new Pf());
+                    return StatsFunctionsNodes.Function3_2Node.create(new Pf());
                 case "qf":
-                    return StatsFunctionsFactory.Function3_2NodeGen.create(new Qf());
+                    return StatsFunctionsNodes.Function3_2Node.create(new Qf());
                 case "df":
-                    return StatsFunctionsFactory.Function3_1NodeGen.create(new Df());
+                    return StatsFunctionsNodes.Function3_1Node.create(new Df());
                 case "dgamma":
-                    return StatsFunctionsFactory.Function3_1NodeGen.create(new DGamma());
+                    return StatsFunctionsNodes.Function3_1Node.create(new DGamma());
                 case "pgamma":
-                    return StatsFunctionsFactory.Function3_2NodeGen.create(new PGamma());
+                    return StatsFunctionsNodes.Function3_2Node.create(new PGamma());
                 case "dchisq":
-                    return StatsFunctionsFactory.Function2_1NodeGen.create(new Chisq.DChisq());
+                    return StatsFunctionsNodes.Function2_1Node.create(new Chisq.DChisq());
                 case "qchisq":
-                    return StatsFunctionsFactory.Function2_2NodeGen.create(new Chisq.QChisq());
+                    return StatsFunctionsNodes.Function2_2Node.create(new Chisq.QChisq());
                 case "qgeom":
-                    return StatsFunctionsFactory.Function2_2NodeGen.create(new Geom.QGeom());
+                    return StatsFunctionsNodes.Function2_2Node.create(new Geom.QGeom());
                 case "pchisq":
-                    return StatsFunctionsFactory.Function2_2NodeGen.create(new Chisq.PChisq());
+                    return StatsFunctionsNodes.Function2_2Node.create(new Chisq.PChisq());
                 case "dexp":
-                    return StatsFunctionsFactory.Function2_1NodeGen.create(new DExp());
+                    return StatsFunctionsNodes.Function2_1Node.create(new DExp());
                 case "pexp":
-                    return StatsFunctionsFactory.Function2_2NodeGen.create(new PExp());
+                    return StatsFunctionsNodes.Function2_2Node.create(new PExp());
                 case "qexp":
-                    return StatsFunctionsFactory.Function2_2NodeGen.create(new QExp());
+                    return StatsFunctionsNodes.Function2_2Node.create(new QExp());
                 case "dgeom":
-                    return StatsFunctionsFactory.Function2_1NodeGen.create(new DGeom());
+                    return StatsFunctionsNodes.Function2_1Node.create(new DGeom());
                 case "dpois":
-                    return StatsFunctionsFactory.Function2_1NodeGen.create(new DPois());
+                    return StatsFunctionsNodes.Function2_1Node.create(new DPois());
                 case "dbeta":
-                    return StatsFunctionsFactory.Function3_1NodeGen.create(new DBeta());
+                    return StatsFunctionsNodes.Function3_1Node.create(new DBeta());
                 case "dnbeta":
-                    return StatsFunctions.Function4_1Node.create(new DNBeta());
+                    return StatsFunctionsNodes.Function4_1Node.create(new DNBeta());
                 case "qnbeta":
-                    return StatsFunctions.Function4_2Node.create(new QNBeta());
+                    return StatsFunctionsNodes.Function4_2Node.create(new QNBeta());
                 case "dnf":
-                    return StatsFunctions.Function4_1Node.create(new Dnf());
+                    return StatsFunctionsNodes.Function4_1Node.create(new Dnf());
                 case "qnf":
-                    return StatsFunctions.Function4_2Node.create(new Qnf());
+                    return StatsFunctionsNodes.Function4_2Node.create(new Qnf());
                 case "pnf":
-                    return StatsFunctions.Function4_2Node.create(new Pnf());
+                    return StatsFunctionsNodes.Function4_2Node.create(new Pnf());
                 case "pnbeta":
-                    return StatsFunctions.Function4_2Node.create(new PNBeta());
+                    return StatsFunctionsNodes.Function4_2Node.create(new PNBeta());
                 case "dt":
-                    return StatsFunctionsFactory.Function2_1NodeGen.create(new Dt());
+                    return StatsFunctionsNodes.Function2_1Node.create(new Dt());
                 case "rlnorm":
                     return RandFunction2Node.createDouble(new LogNormal.RLNorm());
                 case "dlnorm":
-                    return StatsFunctionsFactory.Function3_1NodeGen.create(new DLNorm());
+                    return StatsFunctionsNodes.Function3_1Node.create(new DLNorm());
                 case "qlnorm":
-                    return StatsFunctionsFactory.Function3_2NodeGen.create(new QLNorm());
+                    return StatsFunctionsNodes.Function3_2Node.create(new QLNorm());
                 case "plnorm":
-                    return StatsFunctionsFactory.Function3_2NodeGen.create(new PLNorm());
+                    return StatsFunctionsNodes.Function3_2Node.create(new PLNorm());
                 case "dlogis":
-                    return StatsFunctionsFactory.Function3_1NodeGen.create(new DLogis());
+                    return StatsFunctionsNodes.Function3_1Node.create(new DLogis());
                 case "qlogis":
-                    return StatsFunctionsFactory.Function3_2NodeGen.create(new Logis.QLogis());
+                    return StatsFunctionsNodes.Function3_2Node.create(new Logis.QLogis());
                 case "plogis":
-                    return StatsFunctionsFactory.Function3_2NodeGen.create(new Logis.PLogis());
+                    return StatsFunctionsNodes.Function3_2Node.create(new Logis.PLogis());
                 case "pgeom":
-                    return StatsFunctionsFactory.Function2_2NodeGen.create(new Geom.PGeom());
+                    return StatsFunctionsNodes.Function2_2Node.create(new Geom.PGeom());
                 case "qnbinom":
-                    return StatsFunctionsFactory.Function3_2NodeGen.create(new QNBinomFunc());
+                    return StatsFunctionsNodes.Function3_2Node.create(new QNBinomFunc());
                 case "dnbinom":
-                    return StatsFunctionsFactory.Function3_1NodeGen.create(new DNBinomFunc());
+                    return StatsFunctionsNodes.Function3_1Node.create(new DNBinomFunc());
                 case "pnbinom":
-                    return StatsFunctionsFactory.Function3_2NodeGen.create(new PNBinomFunc());
+                    return StatsFunctionsNodes.Function3_2Node.create(new PNBinomFunc());
                 case "qnbinom_mu":
-                    return StatsFunctionsFactory.Function3_2NodeGen.create(new QNBinomMu());
+                    return StatsFunctionsNodes.Function3_2Node.create(new QNBinomMu());
                 case "dnbinom_mu":
-                    return StatsFunctionsFactory.Function3_1NodeGen.create(new DNBinomMu());
+                    return StatsFunctionsNodes.Function3_1Node.create(new DNBinomMu());
                 case "pnbinom_mu":
-                    return StatsFunctionsFactory.Function3_2NodeGen.create(new PNBinomMu());
+                    return StatsFunctionsNodes.Function3_2Node.create(new PNBinomMu());
+                case "qwilcox":
+                    return StatsFunctionsNodes.Function3_2Node.create(new QWilcox());
+                case "pwilcox":
+                    return StatsFunctionsNodes.Function3_2Node.create(new PWilcox());
+                case "dwilcox":
+                    return StatsFunctionsNodes.Function3_1Node.create(new DWilcox());
                 case "rmultinom":
-                    return RMultinomNodeGen.create();
+                    return RMultinomNode.create();
                 case "Approx":
-                    return StatsFunctionsFactory.ApproxNodeGen.create();
+                    return StatsFunctionsNodes.Approx.create();
                 case "ApproxTest":
-                    return StatsFunctionsFactory.ApproxTestNodeGen.create();
+                    return StatsFunctionsNodes.ApproxTest.create();
                 case "Cdist":
                     return CdistNodeGen.create();
                 case "DoubleCentre":
@@ -538,10 +547,10 @@ public class CallAndExternalFunctions {
                     return getExternalModelBuiltinNode("updateform");
 
                 case "Cdqrls":
-                    return new RInternalCodeBuiltinNode(RContext.getInstance(), "stats", RInternalCode.loadSourceRelativeTo(RandGenerationFunctions.class, "lm.R"), "Cdqrls");
+                    return new RInternalCodeBuiltinNode(RContext.getInstance(), "stats", RInternalCode.loadSourceRelativeTo(RandFunctionsNodes.class, "lm.R"), "Cdqrls");
 
                 case "dnorm":
-                    return StatsFunctionsFactory.Function3_1NodeGen.create(new DNorm());
+                    return StatsFunctionsNodes.Function3_1Node.create(new DNorm());
 
                 // tools
                 case "doTabExpand":
@@ -699,6 +708,8 @@ public class CallAndExternalFunctions {
                     return RprofNodeGen.create();
                 case "Rprofmem":
                     return RprofmemNodeGen.create();
+                case "wilcox_free":
+                    return new WilcoxFreeNode();
                 case "unzip":
                 case "addhistory":
                 case "loadhistory":
diff --git a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/foreign/LookupAdapter.java b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/foreign/LookupAdapter.java
index 5da46c9331..c2ffbc4f9e 100644
--- a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/foreign/LookupAdapter.java
+++ b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/foreign/LookupAdapter.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2015, 2016, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2015, 2017, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -29,7 +29,7 @@ import com.oracle.truffle.api.dsl.Specialization;
 import com.oracle.truffle.api.frame.VirtualFrame;
 import com.oracle.truffle.api.nodes.Node;
 import com.oracle.truffle.api.profiles.BranchProfile;
-import com.oracle.truffle.r.library.stats.RandGenerationFunctions;
+import com.oracle.truffle.r.library.stats.RandFunctionsNodes;
 import com.oracle.truffle.r.nodes.access.vector.ElementAccessMode;
 import com.oracle.truffle.r.nodes.access.vector.ExtractVectorNode;
 import com.oracle.truffle.r.nodes.builtin.RBuiltinNode;
@@ -172,7 +172,7 @@ abstract class LookupAdapter extends RBuiltinNode {
     }
 
     protected static RExternalBuiltinNode getExternalModelBuiltinNode(String name) {
-        return new RInternalCodeBuiltinNode(RContext.getInstance(), "stats", RInternalCode.loadSourceRelativeTo(RandGenerationFunctions.class, "model.R"), name);
+        return new RInternalCodeBuiltinNode(RContext.getInstance(), "stats", RInternalCode.loadSourceRelativeTo(RandFunctionsNodes.class, "model.R"), name);
     }
 
     protected static final int CallNST = DLL.NativeSymbolType.Call.ordinal();
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 1524ea3509..290c7a823c 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
@@ -5,7 +5,7 @@
  *
  * Copyright (c) 1995-2015, The R Core Team
  * Copyright (c) 2003, The R Foundation
- * Copyright (c) 2013, 2016, Oracle and/or its affiliates
+ * Copyright (c) 2013, 2017, Oracle and/or its affiliates
  *
  * All rights reserved.
  */
@@ -302,6 +302,7 @@ public final class RError extends RuntimeException {
         NON_CONFORMABLE_ARRAYS("non-conformable arrays"),
         UNKNOWN_UNNAMED_OBJECT("object not found"),
         CHOOSE_ROUNDING_WARNING("'k' (%g) must be integer, rounded to %d"),
+        WILCOX_TOO_MUCH_MEMORY("running wilcox with m=%g, n=%g would allocate too much memory, returning NaN instead."),
         ONLY_MATRIX_DIAGONALS("only matrix diagonals can be replaced"),
         REPLACEMENT_DIAGONAL_LENGTH("replacement diagonal has wrong length"),
         NA_INTRODUCED_COERCION("NAs introduced by coercion"),
diff --git a/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/RErrorHandling.java b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/RErrorHandling.java
index 43c5f54192..ef3983b463 100644
--- a/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/RErrorHandling.java
+++ b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/RErrorHandling.java
@@ -5,7 +5,7 @@
  *
  * Copyright (c) 1995-2015, The R Core Team
  * Copyright (c) 2003, The R Foundation
- * Copyright (c) 2015, 2016, Oracle and/or its affiliates
+ * Copyright (c) 2015, 2017, Oracle and/or its affiliates
  *
  * All rights reserved.
  */
diff --git a/com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/stats/Arithmetic.java b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/nmath/Arithmetic.java
similarity index 95%
rename from com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/stats/Arithmetic.java
rename to com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/nmath/Arithmetic.java
index 364df33d4b..6a227fce94 100644
--- a/com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/stats/Arithmetic.java
+++ b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/nmath/Arithmetic.java
@@ -6,11 +6,11 @@
  * Copyright (c) 1995, 1996, 1997  Robert Gentleman and Ross Ihaka
  * Copyright (c) 1998-2013, The R Core Team
  * Copyright (c) 2003-2015, The R Foundation
- * Copyright (c) 2016, 2016, Oracle and/or its affiliates
+ * Copyright (c) 2016, 2017, Oracle and/or its affiliates
  *
  * All rights reserved.
  */
-package com.oracle.truffle.r.library.stats;
+package com.oracle.truffle.r.runtime.nmath;
 
 import com.oracle.truffle.r.runtime.RError;
 import com.oracle.truffle.r.runtime.RError.Message;
@@ -25,7 +25,7 @@ public final class Arithmetic {
 
     /* Keep these two in step */
     /*
-     * FIXME: consider using tmp = (LDOUBLE)x1 - floor(q) * (LDOUBLE)x2;
+     * GnuR fix me: consider using tmp = (LDOUBLE)x1 - floor(q) * (LDOUBLE)x2;
      */
     public static double myfmod(double x1, double x2) {
         if (x2 == 0.0) {
diff --git a/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/nmath/Choose.java b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/nmath/Choose.java
new file mode 100644
index 0000000000..c609f9a16d
--- /dev/null
+++ b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/nmath/Choose.java
@@ -0,0 +1,138 @@
+/*
+ * This material is distributed under the GNU General Public License
+ * Version 2. You may review the terms of this license at
+ * http://www.gnu.org/licenses/gpl-2.0.html
+ *
+ * Copyright (c) 2003-2007, The R Core Team
+ * Copyright (c) 2003-2007, The R Foundation
+ * Copyright (c) 2017, Oracle and/or its affiliates
+ *
+ * All rights reserved.
+ */
+
+package com.oracle.truffle.r.runtime.nmath;
+
+import static com.oracle.truffle.r.runtime.nmath.GammaFunctions.lgammafn;
+import static com.oracle.truffle.r.runtime.nmath.GammaFunctions.lgammafnSign;
+
+import com.oracle.truffle.r.runtime.RError.Message;
+
+// transcribed from nmath/choose.c
+
+public class Choose {
+    private static final int K_SMALL_MAX = 30;
+
+    public static double lfastchoose(double n, double k) {
+        return -Math.log(n + 1.) - LBeta.lbeta(n - k + 1., k + 1.);
+    }
+
+    public static double choose(double n, double ka) {
+        double k = ka;
+        if (Double.isNaN(n) || Double.isNaN(ka)) {
+            return n + k;
+        }
+        if (TOMS708.fabs(k - RMath.forceint(k)) > 1e-7) {
+            RMathError.warning(Message.CHOOSE_ROUNDING_WARNING, k, RMath.forceint(k));
+        }
+
+        if (k < K_SMALL_MAX) {
+            // symmetry: this e.g. turns (n=3,k=3) into (n=3,k=0)
+            int intN = (int) n;
+            if (n == intN && intN - k < k && intN >= 0) {
+                k = intN - k;
+            }
+
+            if (k < 0) {
+                return 0;
+            } else if (k == 0) {
+                return 1;
+            }
+
+            double result = n;
+            for (int i = 2; i <= k; i++) {
+                result *= (n - i + 1) / i;
+            }
+            return isInt(n) ? RMath.forceint(result) : result;
+        }
+        if (n < 0) {
+            double factor = isOdd(k) ? -1. : 1.;
+            return factor * choose(-n + k - 1, k);
+        }
+        if (isInt(n)) {
+            double nInt = RMath.forceint(n);
+            if (n < k) {
+                return 0;
+            } else if (n - k < K_SMALL_MAX) {
+                return choose(n, n - k);
+            }
+            return RMath.forceint(Math.exp(lfastchoose(n, k)));
+        }
+        // else non-integer n >= 0
+        if (n < k - 1) {
+            int[] sChoose = new int[1];
+            double result = lfastchoose2(n, k, sChoose);
+            return sChoose[0] * Math.exp(result);
+        }
+        return Math.exp(lfastchoose(n, k));
+    }
+
+    public static double lchoose(double n, double kIn) {
+        double k = RMath.forceint(kIn);
+        /* NaNs propagated correctly */
+        if (Double.isNaN(n) || Double.isNaN(k)) {
+            return n + k;
+        }
+
+        if (TOMS708.fabs(k - kIn) > 1e-7) {
+            RMathError.warning(Message.CHOOSE_ROUNDING_WARNING, kIn, k);
+        }
+        if (k < 2) {
+            if (k < 0) {
+                return Double.NEGATIVE_INFINITY;
+            }
+            if (k == 0) {
+                return 0.;
+            }
+            /* else: k == 1 */
+            return Math.log(TOMS708.fabs(n));
+        }
+        /* else: k >= 2 */
+        if (n < 0) {
+            return lchoose(-n + k - 1, k);
+        } else if (isInt(n)) {
+            double nInt = RMath.forceint(n);
+            if (nInt < k) {
+                return Double.NEGATIVE_INFINITY;
+            }
+            /* k <= n : */
+            if (nInt - k < 2) {
+                return lchoose(nInt, nInt - k);
+            } /* <- Symmetry */
+            /* else: n >= k+2 */
+            return lfastchoose(nInt, k);
+        }
+        /* else non-integer n >= 0 : */
+        if (n < k - 1) {
+            int[] s = new int[1];
+            return lfastchoose2(n, k, s);
+        }
+        return lfastchoose(n, k);
+    }
+
+    /*
+     * mathematically the same: less stable typically, but useful if n-k+1 < 0 :
+     */
+    static double lfastchoose2(double n, double k, int[] sChoose) {
+        double r;
+        r = lgammafnSign(n - k + 1., sChoose);
+        return lgammafn(n + 1.) - lgammafn(k + 1.) - r;
+    }
+
+    private static boolean isOdd(double x) {
+        return x != 2 * Math.floor(x / 2.);
+    }
+
+    private static boolean isInt(double x) {
+        return !DPQ.nonint(x);
+    }
+}
diff --git a/com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/stats/DPQ.java b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/nmath/DPQ.java
similarity index 91%
rename from com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/stats/DPQ.java
rename to com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/nmath/DPQ.java
index 2ec4f83eaa..bdbe2bfd75 100644
--- a/com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/stats/DPQ.java
+++ b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/nmath/DPQ.java
@@ -4,13 +4,11 @@
  * http://www.gnu.org/licenses/gpl-2.0.html
  *
  * Copyright (c) 2000--2014, The R Core Team
- * Copyright (c) 2016, 2016, Oracle and/or its affiliates
+ * Copyright (c) 2016, 2017, 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_LN2;
+package com.oracle.truffle.r.runtime.nmath;
 
 import com.oracle.truffle.r.runtime.RError;
 import com.oracle.truffle.r.runtime.RError.Message;
@@ -53,7 +51,7 @@ public final class DPQ {
 
     // R_D_half (log_p ? -M_LN2 : 0.5)
     public static double rdhalf(boolean logP) {
-        return logP ? -M_LN2 : 0.5;
+        return logP ? -MathConstants.M_LN2 : 0.5;
     }
 
     // R_D__1
@@ -97,7 +95,7 @@ public final class DPQ {
 
     // R_DT_val
     public static double rdtval(double x, boolean lowerTail, boolean logP) {
-        return lowerTail ? rdval(x, true) : rdclog(x, logP);
+        return lowerTail ? rdval(x, logP) : rdclog(x, logP);
     }
 
     public static double rdexp(double x, boolean logP) {
@@ -115,7 +113,7 @@ public final class DPQ {
 
     // R_Log1_Exp
     public static double rlog1exp(double x) {
-        return ((x) > -M_LN2 ? Math.log(-RMath.expm1(x)) : RMath.log1p(-Math.exp(x)));
+        return ((x) > -MathConstants.M_LN2 ? Math.log(-RMath.expm1(x)) : RMath.log1p(-Math.exp(x)));
     }
 
     // R_DT_Clog
@@ -203,9 +201,6 @@ public final class DPQ {
     // #define R_DT_exp(x) R_D_exp(R_D_Lval(x)) /* exp(x) */
     // #define R_DT_Cexp(x) R_D_exp(R_D_Cval(x)) /* exp(1 - x) */
     //
-    // #define R_DT_log(p) (lower_tail? R_D_log(p) : R_D_LExp(p))/* log(p) in qF */
-    // #define R_DT_Clog(p) (lower_tail? R_D_LExp(p): R_D_log(p))/* log(1-p) in qF*/
-    // #define R_DT_Log(p) (lower_tail? (p) : R_Log1_Exp(p))
 
     // FastR helpers:
 
diff --git a/com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/stats/GammaFunctions.java b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/nmath/GammaFunctions.java
similarity index 95%
rename from com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/stats/GammaFunctions.java
rename to com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/nmath/GammaFunctions.java
index a1c57d865d..bdcf8ff0a4 100644
--- a/com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/stats/GammaFunctions.java
+++ b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/nmath/GammaFunctions.java
@@ -16,63 +16,50 @@
  *
  * All rights reserved.
  */
-package com.oracle.truffle.r.library.stats;
-
-import static com.oracle.truffle.r.library.stats.DPQ.rd0;
-import static com.oracle.truffle.r.library.stats.DPQ.rd1;
-import static com.oracle.truffle.r.library.stats.DPQ.rdexp;
-import static com.oracle.truffle.r.library.stats.DPQ.rdt0;
-import static com.oracle.truffle.r.library.stats.DPQ.rdt1;
-import static com.oracle.truffle.r.library.stats.DPQ.rdtclog;
-import static com.oracle.truffle.r.library.stats.DPQ.rdtqiv;
-import static com.oracle.truffle.r.library.stats.DPQ.rlog1exp;
-import static com.oracle.truffle.r.library.stats.MathConstants.DBL_EPSILON;
-import static com.oracle.truffle.r.library.stats.MathConstants.DBL_MIN;
-import static com.oracle.truffle.r.library.stats.MathConstants.M_1_SQRT_2PI;
-import static com.oracle.truffle.r.library.stats.MathConstants.M_LN2;
-import static com.oracle.truffle.r.library.stats.MathConstants.M_SQRT_32;
-import static com.oracle.truffle.r.library.stats.RMath.fmax2;
+package com.oracle.truffle.r.runtime.nmath;
+
+import static com.oracle.truffle.r.runtime.nmath.DPQ.rd0;
+import static com.oracle.truffle.r.runtime.nmath.DPQ.rd1;
+import static com.oracle.truffle.r.runtime.nmath.DPQ.rdexp;
+import static com.oracle.truffle.r.runtime.nmath.DPQ.rdt0;
+import static com.oracle.truffle.r.runtime.nmath.DPQ.rdt1;
+import static com.oracle.truffle.r.runtime.nmath.DPQ.rdtclog;
+import static com.oracle.truffle.r.runtime.nmath.DPQ.rdtqiv;
+import static com.oracle.truffle.r.runtime.nmath.DPQ.rlog1exp;
+import static com.oracle.truffle.r.runtime.nmath.MathConstants.DBL_EPSILON;
+import static com.oracle.truffle.r.runtime.nmath.MathConstants.DBL_MIN;
+import static com.oracle.truffle.r.runtime.nmath.MathConstants.M_1_SQRT_2PI;
+import static com.oracle.truffle.r.runtime.nmath.MathConstants.M_LN2;
+import static com.oracle.truffle.r.runtime.nmath.MathConstants.M_SQRT_32;
 
 import com.oracle.truffle.api.CompilerDirectives.CompilationFinal;
 import com.oracle.truffle.api.CompilerDirectives.TruffleBoundary;
-import com.oracle.truffle.r.library.stats.DPQ.EarlyReturn;
-import com.oracle.truffle.r.library.stats.RMathError.MLError;
-import com.oracle.truffle.r.library.stats.StatsFunctions.Function3_1;
-import com.oracle.truffle.r.library.stats.StatsFunctions.Function3_2;
 import com.oracle.truffle.r.runtime.RError.Message;
 import com.oracle.truffle.r.runtime.RRuntime;
 import com.oracle.truffle.r.runtime.Utils;
+import com.oracle.truffle.r.runtime.nmath.DPQ.EarlyReturn;
+import com.oracle.truffle.r.runtime.nmath.RMathError.MLError;
+import com.oracle.truffle.r.runtime.nmath.distr.DNorm;
+import com.oracle.truffle.r.runtime.nmath.distr.DPois;
+import com.oracle.truffle.r.runtime.nmath.distr.Pnorm;
+import com.oracle.truffle.r.runtime.nmath.distr.Qnorm;
 import com.oracle.truffle.r.runtime.ops.BinaryArithmetic;
 
 /**
- * Java implementation of the qgamma function. The logic was derived from GNU R (see inline
- * comments).
- *
+ * Java implementation of the qgamma and related functions. The logic was derived from GNU R (see
+ * inline comments).
  */
 public abstract class GammaFunctions {
 
     // This is derived from distn.c.
 
-    public static final class QgammaFunc implements Function3_2 {
-        @Override
-        public double evaluate(double p, double shape, double scale, boolean lowerTail, boolean logP) {
-            return GammaFunctions.qgamma(p, shape, scale, lowerTail, logP);
-        }
-    }
-
-    public static final class DGamma implements Function3_1 {
-        @Override
-        public double evaluate(double x, double shape, double scale, boolean giveLog) {
-            return dgamma(x, shape, scale, giveLog);
-        }
-    }
-
     // The remainder of this file is derived from GNU R (mostly nmath): qgamma.c, nmath.h, lgamma.c,
     // gamma.c, stirlerr.c, lgammacor.c, pgamma.c, fmax2.c, dpois.c, bd0.c, dgamma.c, pnorm.c,
     // qnorm.c
 
     // TODO Many of the functions below that are not directly supporting qgamma should eventually be
-    // factored out to support those R functions they represent.
+    // factored out to support those R functions they represent. Note 1/2017: some have been
+    // factored out.
 
     //
     // lgammacor
@@ -110,7 +97,7 @@ public abstract class GammaFunctions {
      * Should be used in places where GnuR itself uses std libc function {@code lgamma}. Under the
      * hood it uses {@link #lgammafn(double)}.
      */
-    static double lgamma(@SuppressWarnings("unused") double x) {
+    public static double lgamma(@SuppressWarnings("unused") double x) {
         return lgammafn(x);
     }
 
@@ -272,7 +259,7 @@ public abstract class GammaFunctions {
     private static final double M_LN_SQRT_PId2 = 0.225791352644727432363097614947;
 
     // convert C's int* sgn to a 1-element int[]
-    private static double lgammafnSign(double x, int[] sgn) {
+    static double lgammafnSign(double x, int[] sgn) {
         double ans;
         double y;
         double sinpiy;
@@ -396,7 +383,7 @@ public abstract class GammaFunctions {
             double lgam1pa = (alpha < 0.5) ? lgamma1p(alpha) : (Math.log(alpha) + g);
             ch = Math.exp((lgam1pa + p1) / alpha + M_LN2);
         } else if (nu > 0.32) { /* using Wilson and Hilferty estimate */
-            x = Random2.qnorm5(p, 0, 1, lowerTail, logp);
+            x = Qnorm.qnorm(p, 0, 1, lowerTail, logp);
             p1 = 2. / (9 * nu);
             ch = nu * Math.pow(x * Math.sqrt(p1) + 1 - p1, 3);
 
@@ -917,7 +904,7 @@ public abstract class GammaFunctions {
             if (b2 != 0) {
                 f = a2 / b2;
                 /* convergence check: relative; "absolute" for very small f : */
-                if (Math.abs(f - of) <= DBL_EPSILON * fmax2(f0, Math.abs(f))) {
+                if (Math.abs(f - of) <= DBL_EPSILON * RMath.fmax2(f0, Math.abs(f))) {
                     return f;
                 }
                 of = f;
@@ -1079,7 +1066,7 @@ public abstract class GammaFunctions {
         }
     } /* ppois_asymp() */
 
-    static double pgammaRaw(double x, double alph, boolean lowerTail, boolean logp) {
+    public static double pgammaRaw(double x, double alph, boolean lowerTail, boolean logp) {
         /* Here, assume that (x,alph) are not NA & alph > 0 . */
 
         double res;
diff --git a/com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/stats/LBeta.java b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/nmath/LBeta.java
similarity index 81%
rename from com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/stats/LBeta.java
rename to com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/nmath/LBeta.java
index c9a23be80b..a4f839b03a 100644
--- a/com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/stats/LBeta.java
+++ b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/nmath/LBeta.java
@@ -6,17 +6,17 @@
  * 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
+ * Copyright (c) 2016, 2017, Oracle and/or its affiliates
  *
  * All rights reserved.
  */
-package com.oracle.truffle.r.library.stats;
+package com.oracle.truffle.r.runtime.nmath;
 
-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;
+import static com.oracle.truffle.r.runtime.nmath.GammaFunctions.gammafn;
+import static com.oracle.truffle.r.runtime.nmath.GammaFunctions.lgamma;
+import static com.oracle.truffle.r.runtime.nmath.GammaFunctions.lgammacor;
+import static com.oracle.truffle.r.runtime.nmath.GammaFunctions.lgammafn;
+import static com.oracle.truffle.r.runtime.nmath.MathConstants.M_LN_SQRT_2PI;
 
 public final class LBeta {
     public static double lbeta(double a, double b) {
diff --git a/com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/stats/MathInit.java b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/nmath/Mach.java
similarity index 82%
rename from com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/stats/MathInit.java
rename to com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/nmath/Mach.java
index b9cad15bb0..2fdee595bc 100644
--- a/com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/stats/MathInit.java
+++ b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/nmath/Mach.java
@@ -3,24 +3,23 @@
  * Version 2. You may review the terms of this license at
  * http://www.gnu.org/licenses/gpl-2.0.html
  *
- * Copyright (c) 2001--2012, The R Core Team
- * Copyright (c) 2016, 2016, Oracle and/or its affiliates
+ * Copyright (C) 1998 Ross Ihaka
+ * Copyright (c) 2000--2014, The R Core Team
+ * Copyright (c) 2016, 2017, Oracle and/or its affiliates
  *
  * All rights reserved.
  */
-package com.oracle.truffle.r.library.stats;
+package com.oracle.truffle.r.runtime.nmath;
 
-import static com.oracle.truffle.r.library.stats.MathConstants.DBL_MIN;
-import static com.oracle.truffle.r.library.stats.MathConstants.M_LOG10_2;
+import static com.oracle.truffle.r.runtime.nmath.MathConstants.DBL_MIN;
+import static com.oracle.truffle.r.runtime.nmath.MathConstants.M_LOG10_2;
 
 import com.oracle.truffle.r.runtime.RInternalError;
 import com.oracle.truffle.r.runtime.RRuntime;
 
-// transcribed from init.c
-
-public final class MathInit {
-    private MathInit() {
-        // private
+public final class Mach {
+    public Mach() {
+        // only static members
     }
 
     // Rf_d1mach transcribed from d1mach.c
@@ -43,7 +42,7 @@ public final class MathInit {
         }
     }
 
-    // Rf_i1mach transcribed from init.c
+    // Rf_i1mach transcribed from i1mach.c
     public static int i1mach(int i) {
         switch (i) {
             case 1:
diff --git a/com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/stats/MathConstants.java b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/nmath/MathConstants.java
similarity index 97%
rename from com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/stats/MathConstants.java
rename to com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/nmath/MathConstants.java
index d7c4b92c62..543ce27dc9 100644
--- a/com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/stats/MathConstants.java
+++ b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/nmath/MathConstants.java
@@ -6,11 +6,11 @@
  * Copyright (C) 1998 Ross Ihaka
  * Copyright (c) 1998--2012, The R Core Team
  * Copyright (c) 2004, The R Foundation
- * Copyright (c) 2013, 2016, Oracle and/or its affiliates
+ * Copyright (c) 2013, 2017, Oracle and/or its affiliates
  *
  * All rights reserved.
  */
-package com.oracle.truffle.r.library.stats;
+package com.oracle.truffle.r.runtime.nmath;
 
 // transcribed from Rmath.h
 
diff --git a/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/nmath/MathFunctions.java b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/nmath/MathFunctions.java
new file mode 100644
index 0000000000..d52694ee16
--- /dev/null
+++ b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/nmath/MathFunctions.java
@@ -0,0 +1,78 @@
+/*
+ * Copyright (c) 2017, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package com.oracle.truffle.r.runtime.nmath;
+
+/**
+ * Defines common interface for math functions operating on scalar values, which is used to
+ * implement common code for the vectorized versions.
+ */
+public class MathFunctions {
+    public interface Function4_2 {
+        double evaluate(double a, double b, double c, double d, boolean x, boolean y);
+    }
+
+    public interface Function4_1 extends Function4_2 {
+        @Override
+        default double evaluate(double a, double b, double c, double d, boolean x, boolean y) {
+            return evaluate(a, b, c, d, x);
+        }
+
+        double evaluate(double a, double b, double c, double d, boolean x);
+    }
+
+    public interface Function3_2 extends Function4_2 {
+        @Override
+        default double evaluate(double a, double b, double c, double d, boolean x, boolean y) {
+            return evaluate(a, b, c, x, y);
+        }
+
+        double evaluate(double a, double b, double c, boolean x, boolean y);
+    }
+
+    public interface Function3_1 extends Function3_2 {
+        @Override
+        default double evaluate(double a, double b, double c, boolean x, boolean y) {
+            return evaluate(a, b, c, x);
+        }
+
+        double evaluate(double a, double b, double c, boolean x);
+    }
+
+    public interface Function2_1 extends Function3_2 {
+        @Override
+        default double evaluate(double a, double b, double c, boolean x, boolean y) {
+            return evaluate(a, b, x);
+        }
+
+        double evaluate(double a, double b, boolean x);
+    }
+
+    public interface Function2_2 extends Function3_2 {
+        @Override
+        default double evaluate(double a, double b, double c, boolean x, boolean y) {
+            return evaluate(a, b, x, y);
+        }
+
+        double evaluate(double a, double b, boolean x, boolean y);
+    }
+}
diff --git a/com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/stats/RMath.java b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/nmath/RMath.java
similarity index 96%
rename from com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/stats/RMath.java
rename to com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/nmath/RMath.java
index 57e33d4af0..214d65f289 100644
--- a/com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/stats/RMath.java
+++ b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/nmath/RMath.java
@@ -10,14 +10,13 @@
  *
  * All rights reserved.
  */
-package com.oracle.truffle.r.library.stats;
+package com.oracle.truffle.r.runtime.nmath;
 
-import static com.oracle.truffle.r.library.stats.LBeta.lbeta;
-import static com.oracle.truffle.r.library.stats.MathConstants.M_LN_SQRT_2PI;
+import static com.oracle.truffle.r.runtime.nmath.MathConstants.M_LN_SQRT_2PI;
 
 import com.oracle.truffle.api.CompilerDirectives.CompilationFinal;
-import com.oracle.truffle.r.library.stats.RMathError.MLError;
 import com.oracle.truffle.r.runtime.RRuntime;
+import com.oracle.truffle.r.runtime.nmath.RMathError.MLError;
 
 /**
  * Encapsulates functions to be found in Rmath.h or in nmath directory in GnuR except for random
@@ -34,10 +33,6 @@ public final class RMath {
         return !Double.isNaN(d);
     }
 
-    public static double lfastchoose(double n, double k) {
-        return -Math.log(n + 1.) - lbeta(n - k + 1., k + 1.);
-    }
-
     /**
      * Implementation of {@code R_forceint}, which is not equal to {@code Math.round}, because it
      * returns {@code double} and so it can handle values that do not fit into long.
@@ -276,7 +271,7 @@ public final class RMath {
                     0.005554733551962801371038690 /* 15.0 */
     };
 
-    static double stirlerr(double n) {
+    public static double stirlerr(double n) {
         double nn;
 
         if (n <= 15.0) {
@@ -308,7 +303,7 @@ public final class RMath {
     /**
      * Evaluates the "deviance part". Transcribed from GnuR.
      */
-    static double bd0(double x, double np) {
+    public static double bd0(double x, double np) {
         double ej;
         double s;
         double s1;
diff --git a/com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/stats/RMathError.java b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/nmath/RMathError.java
similarity index 98%
rename from com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/stats/RMathError.java
rename to com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/nmath/RMathError.java
index 0644a4c012..1a84e36b80 100644
--- a/com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/stats/RMathError.java
+++ b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/nmath/RMathError.java
@@ -8,7 +8,7 @@
  *
  * All rights reserved.
  */
-package com.oracle.truffle.r.library.stats;
+package com.oracle.truffle.r.runtime.nmath;
 
 import com.oracle.truffle.api.CompilerDirectives.TruffleBoundary;
 import com.oracle.truffle.r.runtime.RError;
diff --git a/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/nmath/RandomFunctions.java b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/nmath/RandomFunctions.java
new file mode 100644
index 0000000000..815481e6f4
--- /dev/null
+++ b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/nmath/RandomFunctions.java
@@ -0,0 +1,91 @@
+/*
+ * Copyright (c) 2017, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package com.oracle.truffle.r.runtime.nmath;
+
+import com.oracle.truffle.api.nodes.Node;
+import com.oracle.truffle.r.runtime.nmath.distr.SExp;
+import com.oracle.truffle.r.runtime.nmath.distr.SNorm;
+import com.oracle.truffle.r.runtime.rng.RRNG;
+import com.oracle.truffle.r.runtime.rng.RRNG.NormKind;
+import com.oracle.truffle.r.runtime.rng.RandomNumberGenerator;
+
+/**
+ * Defines common interface for math functions generating a random scalar value, which is used to
+ * implement common code for the vectorized versions.
+ */
+public class RandomFunctions {
+    public abstract static class RandFunction3_Double extends Node {
+        public abstract double execute(double a, double b, double c, RandomNumberProvider rand);
+    }
+
+    public abstract static class RandFunction2_Double extends RandFunction3_Double {
+        public abstract double execute(double a, double b, RandomNumberProvider rand);
+
+        @Override
+        public final double execute(double a, double b, double c, RandomNumberProvider rand) {
+            return execute(a, b, rand);
+        }
+    }
+
+    public abstract static class RandFunction1_Double extends RandFunction2_Double {
+        public abstract double execute(double a, RandomNumberProvider rand);
+
+        @Override
+        public final double execute(double a, double b, RandomNumberProvider rand) {
+            return execute(a, rand);
+        }
+    }
+
+    /**
+     * Convenient wrapper of the current random number generator and current "norm kind" value.
+     */
+    public static final class RandomNumberProvider {
+        final RandomNumberGenerator generator;
+        final NormKind normKind;
+
+        public RandomNumberProvider(RandomNumberGenerator generator, NormKind normKind) {
+            this.generator = generator;
+            this.normKind = normKind;
+        }
+
+        public static RandomNumberProvider fromCurrentRNG() {
+            return new RandomNumberProvider(RRNG.currentGenerator(), RRNG.currentNormKind());
+        }
+
+        public boolean isSame(RandomNumberProvider other) {
+            return this.generator == other.generator && this.normKind == other.normKind;
+        }
+
+        public double unifRand() {
+            return generator.genrandDouble();
+        }
+
+        public double normRand() {
+            return SNorm.normRand(generator, normKind);
+        }
+
+        public double expRand() {
+            return SExp.expRand(generator);
+        }
+    }
+}
diff --git a/com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/stats/TOMS708.java b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/nmath/TOMS708.java
similarity index 99%
rename from com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/stats/TOMS708.java
rename to com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/nmath/TOMS708.java
index a569fe86ca..1b16b566ec 100644
--- a/com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/stats/TOMS708.java
+++ b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/nmath/TOMS708.java
@@ -9,11 +9,13 @@
  *
  * All rights reserved.
  */
-package com.oracle.truffle.r.library.stats;
+package com.oracle.truffle.r.runtime.nmath;
 
-import static com.oracle.truffle.r.library.stats.MathConstants.M_LN_SQRT_2PI;
-import static com.oracle.truffle.r.library.stats.MathConstants.M_SQRT_PI;
-import static com.oracle.truffle.r.library.stats.MathConstants.logspaceAdd;
+import static com.oracle.truffle.r.runtime.nmath.Mach.d1mach;
+import static com.oracle.truffle.r.runtime.nmath.Mach.i1mach;
+import static com.oracle.truffle.r.runtime.nmath.MathConstants.M_LN_SQRT_2PI;
+import static com.oracle.truffle.r.runtime.nmath.MathConstants.M_SQRT_PI;
+import static com.oracle.truffle.r.runtime.nmath.MathConstants.logspaceAdd;
 
 import com.oracle.truffle.api.CompilerDirectives.TruffleBoundary;
 import com.oracle.truffle.r.runtime.RError;
@@ -1539,7 +1541,7 @@ public final class TOMS708 {
         /* -------------------------------------------------------------------- */
 
         double lnb = .69314718055995;
-        int m = (l == 0) ? MathInit.i1mach(16) : MathInit.i1mach(15) - 1;
+        int m = (l == 0) ? i1mach(16) : i1mach(15) - 1;
 
         return m * lnb * .99999;
     } /* exparg */
@@ -1936,7 +1938,7 @@ public final class TOMS708 {
          * amin1(ipmpar(3), 1./spmpar(1))
          */
         double xmax1 = INT_MAX;
-        double d2 = 0.5 / MathInit.d1mach(3); /* = 0.5 / (0.5 * DBL_EPS) = 1/DBL_EPSILON = 2^52 */
+        double d2 = 0.5 / d1mach(3); /* = 0.5 / (0.5 * DBL_EPS) = 1/DBL_EPSILON = 2^52 */
         if (xmax1 > d2) {
             xmax1 = d2;
         }
diff --git a/com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/stats/Cauchy.java b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/nmath/distr/Cauchy.java
similarity index 87%
rename from com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/stats/Cauchy.java
rename to com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/nmath/distr/Cauchy.java
index dfc539f914..3fd8cdec55 100644
--- a/com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/stats/Cauchy.java
+++ b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/nmath/distr/Cauchy.java
@@ -5,20 +5,23 @@
  *
  * Copyright (C) 1998 Ross Ihaka
  * Copyright (c) 1998--2008, The R Core Team
- * Copyright (c) 2016, 2016, Oracle and/or its affiliates
+ * Copyright (c) 2016, 2017, 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_PI;
-import static com.oracle.truffle.r.library.stats.TOMS708.fabs;
-
-import com.oracle.truffle.r.library.stats.DPQ.EarlyReturn;
-import com.oracle.truffle.r.library.stats.RandGenerationFunctions.RandFunction2_Double;
-import com.oracle.truffle.r.library.stats.RandGenerationFunctions.RandomNumberProvider;
-import com.oracle.truffle.r.library.stats.StatsFunctions.Function3_1;
-import com.oracle.truffle.r.library.stats.StatsFunctions.Function3_2;
+package com.oracle.truffle.r.runtime.nmath.distr;
+
+import static com.oracle.truffle.r.runtime.nmath.MathConstants.M_PI;
+import static com.oracle.truffle.r.runtime.nmath.TOMS708.fabs;
+
+import com.oracle.truffle.r.runtime.nmath.DPQ;
+import com.oracle.truffle.r.runtime.nmath.DPQ.EarlyReturn;
+import com.oracle.truffle.r.runtime.nmath.MathFunctions.Function3_1;
+import com.oracle.truffle.r.runtime.nmath.MathFunctions.Function3_2;
+import com.oracle.truffle.r.runtime.nmath.RMath;
+import com.oracle.truffle.r.runtime.nmath.RMathError;
+import com.oracle.truffle.r.runtime.nmath.RandomFunctions.RandFunction2_Double;
+import com.oracle.truffle.r.runtime.nmath.RandomFunctions.RandomNumberProvider;
 
 public final class Cauchy {
     private Cauchy() {
diff --git a/com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/stats/Chisq.java b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/nmath/distr/Chisq.java
similarity index 70%
rename from com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/stats/Chisq.java
rename to com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/nmath/distr/Chisq.java
index 45042cb049..3d79d3d43f 100644
--- a/com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/stats/Chisq.java
+++ b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/nmath/distr/Chisq.java
@@ -5,20 +5,21 @@
  *
  * Copyright (C) 1998 Ross Ihaka
  * Copyright (c) 2000, The R Core Team
- * Copyright (c) 2016, Oracle and/or its affiliates
+ * Copyright (c) 2016, 2017, Oracle and/or its affiliates
  *
  * All rights reserved.
  */
-package com.oracle.truffle.r.library.stats;
+package com.oracle.truffle.r.runtime.nmath.distr;
 
-import static com.oracle.truffle.r.library.stats.GammaFunctions.dgamma;
-import static com.oracle.truffle.r.library.stats.GammaFunctions.pgamma;
-import static com.oracle.truffle.r.library.stats.GammaFunctions.qgamma;
+import static com.oracle.truffle.r.runtime.nmath.GammaFunctions.dgamma;
+import static com.oracle.truffle.r.runtime.nmath.GammaFunctions.pgamma;
+import static com.oracle.truffle.r.runtime.nmath.GammaFunctions.qgamma;
 
-import com.oracle.truffle.r.library.stats.RandGenerationFunctions.RandFunction1_Double;
-import com.oracle.truffle.r.library.stats.RandGenerationFunctions.RandomNumberProvider;
-import com.oracle.truffle.r.library.stats.StatsFunctions.Function2_1;
-import com.oracle.truffle.r.library.stats.StatsFunctions.Function2_2;
+import com.oracle.truffle.r.runtime.nmath.MathFunctions.Function2_1;
+import com.oracle.truffle.r.runtime.nmath.MathFunctions.Function2_2;
+import com.oracle.truffle.r.runtime.nmath.RMathError;
+import com.oracle.truffle.r.runtime.nmath.RandomFunctions.RandFunction1_Double;
+import com.oracle.truffle.r.runtime.nmath.RandomFunctions.RandomNumberProvider;
 
 public final class Chisq {
     private Chisq() {
diff --git a/com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/stats/DBeta.java b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/nmath/distr/DBeta.java
similarity index 89%
rename from com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/stats/DBeta.java
rename to com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/nmath/distr/DBeta.java
index 4b60d50296..d0f9dcf945 100644
--- a/com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/stats/DBeta.java
+++ b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/nmath/distr/DBeta.java
@@ -4,17 +4,19 @@
  * http://www.gnu.org/licenses/gpl-2.0.html
  *
  * Copyright (c) 2000--2014, The R Core Team
- * Copyright (c) 2016, Oracle and/or its affiliates
+ * Copyright (c) 2016, 2017, Oracle and/or its affiliates
  *
  * All rights reserved.
  */
 // Acknowledgement from GnuR header:
 // Author: Catherine Loader, catherine@research.bell-labs.com, October 23, 2000.
-package com.oracle.truffle.r.library.stats;
+package com.oracle.truffle.r.runtime.nmath.distr;
 
-import static com.oracle.truffle.r.library.stats.LBeta.lbeta;
+import static com.oracle.truffle.r.runtime.nmath.LBeta.lbeta;
 
-import com.oracle.truffle.r.library.stats.StatsFunctions.Function3_1;
+import com.oracle.truffle.r.runtime.nmath.DPQ;
+import com.oracle.truffle.r.runtime.nmath.MathFunctions.Function3_1;
+import com.oracle.truffle.r.runtime.nmath.RMathError;
 
 public final class DBeta implements Function3_1 {
     @Override
diff --git a/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/nmath/distr/DGamma.java b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/nmath/distr/DGamma.java
new file mode 100644
index 0000000000..1674365c26
--- /dev/null
+++ b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/nmath/distr/DGamma.java
@@ -0,0 +1,33 @@
+/*
+ * Copyright (c) 2017, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package com.oracle.truffle.r.runtime.nmath.distr;
+
+import com.oracle.truffle.r.runtime.nmath.GammaFunctions;
+import com.oracle.truffle.r.runtime.nmath.MathFunctions.Function3_1;
+
+public final class DGamma implements Function3_1 {
+    @Override
+    public double evaluate(double x, double shape, double scale, boolean giveLog) {
+        return GammaFunctions.dgamma(x, shape, scale, giveLog);
+    }
+}
diff --git a/com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/stats/DHyper.java b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/nmath/distr/DHyper.java
similarity index 72%
rename from com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/stats/DHyper.java
rename to com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/nmath/distr/DHyper.java
index 1b569cd453..5fa9a4adfe 100644
--- a/com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/stats/DHyper.java
+++ b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/nmath/distr/DHyper.java
@@ -4,7 +4,7 @@
  * http://www.gnu.org/licenses/gpl-2.0.html
  *
  * Copyright (c) 2000-2014, The R Core Team
- * Copyright (c) 2016, Oracle and/or its affiliates
+ * Copyright (c) 2016, 2017, Oracle and/or its affiliates
  *
  * All rights reserved.
  */
@@ -14,12 +14,13 @@
  *    October 23, 2000.
  *
  */
-package com.oracle.truffle.r.library.stats;
+package com.oracle.truffle.r.runtime.nmath.distr;
 
-import static com.oracle.truffle.r.library.stats.Dbinom.dbinomRaw;
-
-import com.oracle.truffle.r.library.stats.DPQ.EarlyReturn;
-import com.oracle.truffle.r.library.stats.StatsFunctions.Function4_1;
+import com.oracle.truffle.r.runtime.nmath.DPQ;
+import com.oracle.truffle.r.runtime.nmath.DPQ.EarlyReturn;
+import com.oracle.truffle.r.runtime.nmath.MathFunctions.Function4_1;
+import com.oracle.truffle.r.runtime.nmath.RMath;
+import com.oracle.truffle.r.runtime.nmath.RMathError;
 
 public final class DHyper implements Function4_1 {
     @Override
@@ -56,9 +57,9 @@ public final class DHyper implements Function4_1 {
         double p = in / (ir + ib);
         double q = (ir + ib - in) / (ir + ib);
 
-        double p1 = dbinomRaw(ix, ir, p, q, giveLog);
-        double p2 = dbinomRaw(in - ix, ib, p, q, giveLog);
-        double p3 = dbinomRaw(in, ir + ib, p, q, giveLog);
+        double p1 = Dbinom.dbinomRaw(ix, ir, p, q, giveLog);
+        double p2 = Dbinom.dbinomRaw(in - ix, ib, p, q, giveLog);
+        double p3 = Dbinom.dbinomRaw(in, ir + ib, p, q, giveLog);
 
         return (giveLog) ? p1 + p2 - p3 : p1 * p2 / p3;
     }
diff --git a/com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/stats/DNBeta.java b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/nmath/distr/DNBeta.java
similarity index 91%
rename from com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/stats/DNBeta.java
rename to com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/nmath/distr/DNBeta.java
index 4410c96c63..10f3f9931c 100644
--- a/com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/stats/DNBeta.java
+++ b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/nmath/distr/DNBeta.java
@@ -9,11 +9,13 @@
  *
  * All rights reserved.
  */
-package com.oracle.truffle.r.library.stats;
+package com.oracle.truffle.r.runtime.nmath.distr;
 
-import static com.oracle.truffle.r.library.stats.DPois.dpoisRaw;
+import static com.oracle.truffle.r.runtime.nmath.distr.DPois.dpoisRaw;
 
-import com.oracle.truffle.r.library.stats.StatsFunctions.Function4_1;
+import com.oracle.truffle.r.runtime.nmath.DPQ;
+import com.oracle.truffle.r.runtime.nmath.MathFunctions.Function4_1;
+import com.oracle.truffle.r.runtime.nmath.RMathError;
 
 public final class DNBeta implements Function4_1 {
     private static final double eps = 1.e-15;
diff --git a/com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/stats/DNBinom.java b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/nmath/distr/DNBinom.java
similarity index 84%
rename from com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/stats/DNBinom.java
rename to com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/nmath/distr/DNBinom.java
index f9acf7754f..db4450b3df 100644
--- a/com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/stats/DNBinom.java
+++ b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/nmath/distr/DNBinom.java
@@ -4,7 +4,7 @@
  * http://www.gnu.org/licenses/gpl-2.0.html
  *
  * Copyright (c) 2000--2016, The R Core Team
- * Copyright (c) 2016, Oracle and/or its affiliates
+ * Copyright (c) 2016, 2017, Oracle and/or its affiliates
  *
  * All rights reserved.
  */
@@ -16,16 +16,18 @@
  *    dnbinom_mu(): Martin Maechler, June 2008
  */
 
-package com.oracle.truffle.r.library.stats;
+package com.oracle.truffle.r.runtime.nmath.distr;
 
-import static com.oracle.truffle.r.library.stats.DPois.dpoisRaw;
-import static com.oracle.truffle.r.library.stats.Dbinom.dbinomRaw;
-import static com.oracle.truffle.r.library.stats.GammaFunctions.lgamma;
-import static com.oracle.truffle.r.library.stats.MathConstants.DBL_MAX;
+import static com.oracle.truffle.r.runtime.nmath.GammaFunctions.lgamma;
+import static com.oracle.truffle.r.runtime.nmath.MathConstants.DBL_MAX;
+import static com.oracle.truffle.r.runtime.nmath.distr.DPois.dpoisRaw;
 
 import com.oracle.truffle.api.profiles.BranchProfile;
-import com.oracle.truffle.r.library.stats.DPQ.EarlyReturn;
-import com.oracle.truffle.r.library.stats.StatsFunctions.Function3_1;
+import com.oracle.truffle.r.runtime.nmath.DPQ;
+import com.oracle.truffle.r.runtime.nmath.DPQ.EarlyReturn;
+import com.oracle.truffle.r.runtime.nmath.MathFunctions.Function3_1;
+import com.oracle.truffle.r.runtime.nmath.RMath;
+import com.oracle.truffle.r.runtime.nmath.RMathError;
 
 public final class DNBinom {
     private DNBinom() {
@@ -61,7 +63,7 @@ public final class DNBinom {
             }
             double ix = RMath.forceint(x);
             double size = Double.isFinite(sizeIn) ? sizeIn : DBL_MAX;
-            double ans = dbinomRaw(size, ix + size, prob, 1 - prob, giveLog);
+            double ans = Dbinom.dbinomRaw(size, ix + size, prob, 1 - prob, giveLog);
             double p = size / (size + ix);
             return giveLog ? Math.log(p) + ans : p * ans;
         }
@@ -119,7 +121,7 @@ public final class DNBinom {
                  * so close that n_ - x_ loses accuracy
                  */
                 double p = size / (size + x);
-                double ans = dbinomRaw(size, x + size, size / (size + mu), mu / (size + mu), giveLog);
+                double ans = Dbinom.dbinomRaw(size, x + size, size / (size + mu), mu / (size + mu), giveLog);
                 return ((giveLog) ? Math.log(p) + ans : p * ans);
             }
         }
diff --git a/com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/stats/DNChisq.java b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/nmath/distr/DNChisq.java
similarity index 90%
rename from com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/stats/DNChisq.java
rename to com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/nmath/distr/DNChisq.java
index 656bb8daa0..586a883039 100644
--- a/com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/stats/DNChisq.java
+++ b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/nmath/distr/DNChisq.java
@@ -10,12 +10,14 @@
  *
  * All rights reserved.
  */
-package com.oracle.truffle.r.library.stats;
+package com.oracle.truffle.r.runtime.nmath.distr;
 
-import static com.oracle.truffle.r.library.stats.DPois.dpoisRaw;
+import static com.oracle.truffle.r.runtime.nmath.distr.DPois.dpoisRaw;
 
-import com.oracle.truffle.r.library.stats.Chisq.DChisq;
-import com.oracle.truffle.r.library.stats.StatsFunctions.Function3_1;
+import com.oracle.truffle.r.runtime.nmath.DPQ;
+import com.oracle.truffle.r.runtime.nmath.MathFunctions.Function3_1;
+import com.oracle.truffle.r.runtime.nmath.RMathError;
+import com.oracle.truffle.r.runtime.nmath.distr.Chisq.DChisq;
 
 public final class DNChisq implements Function3_1 {
     private static final double eps = 5e-15;
diff --git a/com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/stats/DNorm.java b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/nmath/distr/DNorm.java
similarity index 71%
rename from com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/stats/DNorm.java
rename to com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/nmath/distr/DNorm.java
index bdccc0beeb..599a3aedff 100644
--- a/com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/stats/DNorm.java
+++ b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/nmath/distr/DNorm.java
@@ -5,17 +5,17 @@
  *
  * Copyright (c) 1995-2012, The R Core Team
  * Copyright (c) 2003, The R Foundation
- * Copyright (c) 2015, 2016, Oracle and/or its affiliates
+ * Copyright (c) 2015, 2017, Oracle and/or its affiliates
  *
  * All rights reserved.
  */
 
-package com.oracle.truffle.r.library.stats;
+package com.oracle.truffle.r.runtime.nmath.distr;
 
-import static com.oracle.truffle.r.library.stats.MathConstants.M_1_SQRT_2PI;
-import static com.oracle.truffle.r.library.stats.MathConstants.M_LN_SQRT_2PI;
-
-import com.oracle.truffle.r.library.stats.StatsFunctions.Function3_1;
+import com.oracle.truffle.r.runtime.nmath.DPQ;
+import com.oracle.truffle.r.runtime.nmath.MathConstants;
+import com.oracle.truffle.r.runtime.nmath.MathFunctions.Function3_1;
+import com.oracle.truffle.r.runtime.nmath.RMathError;
 
 public final class DNorm implements Function3_1 {
     @Override
@@ -47,8 +47,8 @@ public final class DNorm implements Function3_1 {
         }
 
         if (giveLog) {
-            return -(M_LN_SQRT_2PI + 0.5 * x * x + Math.log(sigma));
+            return -(MathConstants.M_LN_SQRT_2PI + 0.5 * x * x + Math.log(sigma));
         }
-        return M_1_SQRT_2PI * Math.exp(-0.5 * x * x) / sigma;
+        return MathConstants.M_1_SQRT_2PI * Math.exp(-0.5 * x * x) / sigma;
     }
 }
diff --git a/com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/stats/DPois.java b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/nmath/distr/DPois.java
similarity index 69%
rename from com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/stats/DPois.java
rename to com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/nmath/distr/DPois.java
index 82dc7bb0e0..eb04912812 100644
--- a/com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/stats/DPois.java
+++ b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/nmath/distr/DPois.java
@@ -10,19 +10,23 @@
  */
 // Acknowledgement from GnuR header:
 // Author: Catherine Loader, catherine@research.bell-labs.com, October 23, 2000.
-package com.oracle.truffle.r.library.stats;
+package com.oracle.truffle.r.runtime.nmath.distr;
 
-import static com.oracle.truffle.r.library.stats.DPQ.rd0;
-import static com.oracle.truffle.r.library.stats.DPQ.rd1;
-import static com.oracle.truffle.r.library.stats.DPQ.rdexp;
-import static com.oracle.truffle.r.library.stats.DPQ.rdfexp;
-import static com.oracle.truffle.r.library.stats.MathConstants.DBL_MIN;
-import static com.oracle.truffle.r.library.stats.MathConstants.M_2PI;
-import static com.oracle.truffle.r.library.stats.RMath.forceint;
+import static com.oracle.truffle.r.runtime.nmath.DPQ.rd0;
+import static com.oracle.truffle.r.runtime.nmath.DPQ.rd1;
+import static com.oracle.truffle.r.runtime.nmath.DPQ.rdexp;
+import static com.oracle.truffle.r.runtime.nmath.DPQ.rdfexp;
+import static com.oracle.truffle.r.runtime.nmath.MathConstants.DBL_MIN;
+import static com.oracle.truffle.r.runtime.nmath.MathConstants.M_2PI;
+import static com.oracle.truffle.r.runtime.nmath.RMath.forceint;
 
-import com.oracle.truffle.r.library.stats.DPQ.EarlyReturn;
-import com.oracle.truffle.r.library.stats.StatsFunctions.Function2_1;
 import com.oracle.truffle.r.runtime.RRuntime;
+import com.oracle.truffle.r.runtime.nmath.DPQ;
+import com.oracle.truffle.r.runtime.nmath.DPQ.EarlyReturn;
+import com.oracle.truffle.r.runtime.nmath.GammaFunctions;
+import com.oracle.truffle.r.runtime.nmath.MathFunctions.Function2_1;
+import com.oracle.truffle.r.runtime.nmath.RMath;
+import com.oracle.truffle.r.runtime.nmath.RMathError;
 
 public final class DPois implements Function2_1 {
     @Override
diff --git a/com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/stats/Dbinom.java b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/nmath/distr/Dbinom.java
similarity index 87%
rename from com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/stats/Dbinom.java
rename to com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/nmath/distr/Dbinom.java
index a44f262782..b0abe4b216 100644
--- a/com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/stats/Dbinom.java
+++ b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/nmath/distr/Dbinom.java
@@ -14,14 +14,18 @@
  *   Catherine Loader, catherine@research.bell-labs.com.
  *   October 23, 2000.
  */
-package com.oracle.truffle.r.library.stats;
+package com.oracle.truffle.r.runtime.nmath.distr;
 
 import com.oracle.truffle.api.profiles.BranchProfile;
-import com.oracle.truffle.r.library.stats.DPQ.EarlyReturn;
+import com.oracle.truffle.r.runtime.nmath.DPQ;
+import com.oracle.truffle.r.runtime.nmath.DPQ.EarlyReturn;
+import com.oracle.truffle.r.runtime.nmath.MathConstants;
+import com.oracle.truffle.r.runtime.nmath.MathFunctions.Function3_1;
+import com.oracle.truffle.r.runtime.nmath.RMath;
 
 // transcribed from dbinom.c
 
-public final class Dbinom implements StatsFunctions.Function3_1 {
+public final class Dbinom implements Function3_1 {
 
     private final BranchProfile nanProfile = BranchProfile.create();
 
diff --git a/com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/stats/Df.java b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/nmath/distr/Df.java
similarity index 78%
rename from com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/stats/Df.java
rename to com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/nmath/distr/Df.java
index 90d58c8260..2068927eb8 100644
--- a/com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/stats/Df.java
+++ b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/nmath/distr/Df.java
@@ -4,18 +4,19 @@
  * http://www.gnu.org/licenses/gpl-2.0.html
  *
  * Copyright (c) 2000--2014, The R Core Team
- * Copyright (c) 2016, Oracle and/or its affiliates
+ * Copyright (c) 2016, 2017, Oracle and/or its affiliates
  *
  * All rights reserved.
  */
 // Acknowledgement from GnuR header:
 // Author: Catherine Loader, catherine@research.bell-labs.com, October 23, 2000.
-package com.oracle.truffle.r.library.stats;
+package com.oracle.truffle.r.runtime.nmath.distr;
 
-import static com.oracle.truffle.r.library.stats.Dbinom.dbinomRaw;
-import static com.oracle.truffle.r.library.stats.GammaFunctions.dgamma;
+import static com.oracle.truffle.r.runtime.nmath.GammaFunctions.dgamma;
 
-import com.oracle.truffle.r.library.stats.StatsFunctions.Function3_1;
+import com.oracle.truffle.r.runtime.nmath.DPQ;
+import com.oracle.truffle.r.runtime.nmath.MathFunctions.Function3_1;
+import com.oracle.truffle.r.runtime.nmath.RMathError;
 
 public final class Df implements Function3_1 {
     @Override
@@ -60,10 +61,10 @@ public final class Df implements Function3_1 {
 
         if (m >= 2) {
             f = m * q / 2;
-            dens = dbinomRaw((m - 2) / 2, (m + n - 2) / 2, p, q, giveLog);
+            dens = Dbinom.dbinomRaw((m - 2) / 2, (m + n - 2) / 2, p, q, giveLog);
         } else {
             f = m * m * q / (2 * p * (m + n));
-            dens = dbinomRaw(m / 2, (m + n) / 2, p, q, giveLog);
+            dens = Dbinom.dbinomRaw(m / 2, (m + n) / 2, p, q, giveLog);
         }
         return (giveLog ? Math.log(f) + dens : f * dens);
     }
diff --git a/com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/stats/Dnf.java b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/nmath/distr/Dnf.java
similarity index 87%
rename from com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/stats/Dnf.java
rename to com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/nmath/distr/Dnf.java
index 2afc8f5e13..9e3b457175 100644
--- a/com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/stats/Dnf.java
+++ b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/nmath/distr/Dnf.java
@@ -4,7 +4,7 @@
  * http://www.gnu.org/licenses/gpl-2.0.html
  *
  * Copyright (c) 2006, The R Core Team
- * Copyright (c) 2016, Oracle and/or its affiliates
+ * Copyright (c) 2016, 2017, Oracle and/or its affiliates
  *
  * All rights reserved.
  */
@@ -14,11 +14,14 @@
  *    April 13, 2006.
  *
  */
-package com.oracle.truffle.r.library.stats;
+package com.oracle.truffle.r.runtime.nmath.distr;
 
-import static com.oracle.truffle.r.library.stats.GammaFunctions.dgamma;
+import static com.oracle.truffle.r.runtime.nmath.GammaFunctions.dgamma;
 
-import com.oracle.truffle.r.library.stats.StatsFunctions.Function4_1;
+import com.oracle.truffle.r.runtime.nmath.DPQ;
+import com.oracle.truffle.r.runtime.nmath.MathFunctions.Function4_1;
+import com.oracle.truffle.r.runtime.nmath.RMath;
+import com.oracle.truffle.r.runtime.nmath.RMathError;
 
 public final class Dnf implements Function4_1 {
     private final DNChisq dnchisq = new DNChisq();
diff --git a/com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/stats/Dt.java b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/nmath/distr/Dt.java
similarity index 82%
rename from com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/stats/Dt.java
rename to com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/nmath/distr/Dt.java
index 86cc494305..0ad654b1ed 100644
--- a/com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/stats/Dt.java
+++ b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/nmath/distr/Dt.java
@@ -10,15 +10,17 @@
  */
 // Acknowledgement from GnuR header:
 // Author: Catherine Loader, catherine@research.bell-labs.com, October 23, 2000.
-package com.oracle.truffle.r.library.stats;
+package com.oracle.truffle.r.runtime.nmath.distr;
 
-import static com.oracle.truffle.r.library.stats.MathConstants.DBL_EPSILON;
-import static com.oracle.truffle.r.library.stats.MathConstants.M_1_SQRT_2PI;
-import static com.oracle.truffle.r.library.stats.MathConstants.M_LN_SQRT_2PI;
-import static com.oracle.truffle.r.library.stats.RMath.bd0;
-import static com.oracle.truffle.r.library.stats.RMath.stirlerr;
+import static com.oracle.truffle.r.runtime.nmath.MathConstants.DBL_EPSILON;
+import static com.oracle.truffle.r.runtime.nmath.MathConstants.M_1_SQRT_2PI;
+import static com.oracle.truffle.r.runtime.nmath.MathConstants.M_LN_SQRT_2PI;
+import static com.oracle.truffle.r.runtime.nmath.RMath.bd0;
+import static com.oracle.truffle.r.runtime.nmath.RMath.stirlerr;
 
-import com.oracle.truffle.r.library.stats.StatsFunctions.Function2_1;
+import com.oracle.truffle.r.runtime.nmath.DPQ;
+import com.oracle.truffle.r.runtime.nmath.MathFunctions.Function2_1;
+import com.oracle.truffle.r.runtime.nmath.RMathError;
 
 public final class Dt implements Function2_1 {
     private static final DNorm dnorm = new DNorm();
diff --git a/com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/stats/Exp.java b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/nmath/distr/Exp.java
similarity index 81%
rename from com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/stats/Exp.java
rename to com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/nmath/distr/Exp.java
index 76df1c61e9..9d51c95b75 100644
--- a/com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/stats/Exp.java
+++ b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/nmath/distr/Exp.java
@@ -5,17 +5,20 @@
  *
  * Copyright (C) 1998 Ross Ihaka
  * Copyright (c) 2000, The R Core Team
- * Copyright (c) 2016, Oracle and/or its affiliates
+ * Copyright (c) 2016, 2017, Oracle and/or its affiliates
  *
  * All rights reserved.
  */
-package com.oracle.truffle.r.library.stats;
+package com.oracle.truffle.r.runtime.nmath.distr;
 
-import com.oracle.truffle.r.library.stats.DPQ.EarlyReturn;
-import com.oracle.truffle.r.library.stats.RandGenerationFunctions.RandFunction1_Double;
-import com.oracle.truffle.r.library.stats.RandGenerationFunctions.RandomNumberProvider;
-import com.oracle.truffle.r.library.stats.StatsFunctions.Function2_1;
-import com.oracle.truffle.r.library.stats.StatsFunctions.Function2_2;
+import com.oracle.truffle.r.runtime.nmath.DPQ;
+import com.oracle.truffle.r.runtime.nmath.DPQ.EarlyReturn;
+import com.oracle.truffle.r.runtime.nmath.MathFunctions.Function2_1;
+import com.oracle.truffle.r.runtime.nmath.MathFunctions.Function2_2;
+import com.oracle.truffle.r.runtime.nmath.RMath;
+import com.oracle.truffle.r.runtime.nmath.RMathError;
+import com.oracle.truffle.r.runtime.nmath.RandomFunctions.RandFunction1_Double;
+import com.oracle.truffle.r.runtime.nmath.RandomFunctions.RandomNumberProvider;
 
 public final class Exp {
     private Exp() {
diff --git a/com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/stats/Geom.java b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/nmath/distr/Geom.java
similarity index 85%
rename from com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/stats/Geom.java
rename to com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/nmath/distr/Geom.java
index 03670cdb79..0ab8fbae5f 100644
--- a/com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/stats/Geom.java
+++ b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/nmath/distr/Geom.java
@@ -5,7 +5,7 @@
  *
  * Copyright (C) 1998 Ross Ihaka
  * Copyright (c) 1998--2008, The R Core Team
- * Copyright (c) 2016, Oracle and/or its affiliates
+ * Copyright (c) 2016, 2017, Oracle and/or its affiliates
  *
  * All rights reserved.
  */
@@ -25,15 +25,18 @@
  * Copyright (C) 2004--2005 The R Foundation
  * Copyright (c) 2016, Oracle and/or its affiliates
  */
-package com.oracle.truffle.r.library.stats;
+package com.oracle.truffle.r.runtime.nmath.distr;
 
-import static com.oracle.truffle.r.library.stats.RMath.forceint;
+import static com.oracle.truffle.r.runtime.nmath.RMath.forceint;
 
-import com.oracle.truffle.r.library.stats.DPQ.EarlyReturn;
-import com.oracle.truffle.r.library.stats.RandGenerationFunctions.RandFunction1_Double;
-import com.oracle.truffle.r.library.stats.RandGenerationFunctions.RandomNumberProvider;
-import com.oracle.truffle.r.library.stats.StatsFunctions.Function2_1;
-import com.oracle.truffle.r.library.stats.StatsFunctions.Function2_2;
+import com.oracle.truffle.r.runtime.nmath.DPQ;
+import com.oracle.truffle.r.runtime.nmath.DPQ.EarlyReturn;
+import com.oracle.truffle.r.runtime.nmath.MathFunctions.Function2_1;
+import com.oracle.truffle.r.runtime.nmath.MathFunctions.Function2_2;
+import com.oracle.truffle.r.runtime.nmath.RMath;
+import com.oracle.truffle.r.runtime.nmath.RMathError;
+import com.oracle.truffle.r.runtime.nmath.RandomFunctions.RandFunction1_Double;
+import com.oracle.truffle.r.runtime.nmath.RandomFunctions.RandomNumberProvider;
 
 public final class Geom {
     private Geom() {
diff --git a/com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/stats/LogNormal.java b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/nmath/distr/LogNormal.java
similarity index 83%
rename from com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/stats/LogNormal.java
rename to com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/nmath/distr/LogNormal.java
index 9384ad6576..b5763fc854 100644
--- a/com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/stats/LogNormal.java
+++ b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/nmath/distr/LogNormal.java
@@ -6,17 +6,20 @@
  * Copyright (C) 1998 Ross Ihaka
  * Copyright (c) 2000--2014, The R Core Team
  * Copyright (c) 2005, The R Foundation
- * Copyright (c) 2016, Oracle and/or its affiliates
+ * Copyright (c) 2016, 2017, Oracle and/or its affiliates
  *
  * All rights reserved.
  */
-package com.oracle.truffle.r.library.stats;
+package com.oracle.truffle.r.runtime.nmath.distr;
 
-import com.oracle.truffle.r.library.stats.DPQ.EarlyReturn;
-import com.oracle.truffle.r.library.stats.RandGenerationFunctions.RandFunction2_Double;
-import com.oracle.truffle.r.library.stats.RandGenerationFunctions.RandomNumberProvider;
-import com.oracle.truffle.r.library.stats.StatsFunctions.Function3_1;
-import com.oracle.truffle.r.library.stats.StatsFunctions.Function3_2;
+import com.oracle.truffle.r.runtime.nmath.DPQ;
+import com.oracle.truffle.r.runtime.nmath.DPQ.EarlyReturn;
+import com.oracle.truffle.r.runtime.nmath.MathConstants;
+import com.oracle.truffle.r.runtime.nmath.MathFunctions.Function3_1;
+import com.oracle.truffle.r.runtime.nmath.MathFunctions.Function3_2;
+import com.oracle.truffle.r.runtime.nmath.RMathError;
+import com.oracle.truffle.r.runtime.nmath.RandomFunctions.RandFunction2_Double;
+import com.oracle.truffle.r.runtime.nmath.RandomFunctions.RandomNumberProvider;
 
 public final class LogNormal {
     private LogNormal() {
diff --git a/com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/stats/Logis.java b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/nmath/distr/Logis.java
similarity index 86%
rename from com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/stats/Logis.java
rename to com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/nmath/distr/Logis.java
index b810fbae9f..3bb60b17a6 100644
--- a/com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/stats/Logis.java
+++ b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/nmath/distr/Logis.java
@@ -5,7 +5,7 @@
  *
  * Copyright (C) 1998 Ross Ihaka
  * Copyright (c) 1998--2008, The R Core Team
- * Copyright (c) 2016, 2016, Oracle and/or its affiliates
+ * Copyright (c) 2016, 2017, Oracle and/or its affiliates
  *
  * All rights reserved.
  */
@@ -13,13 +13,17 @@
  *  Copyright (C) 1995, 1996    Robert Gentleman and Ross Ihaka
  *  Copyright (C) 2000          The R Core Team
  */
-package com.oracle.truffle.r.library.stats;
-
-import com.oracle.truffle.r.library.stats.DPQ.EarlyReturn;
-import com.oracle.truffle.r.library.stats.RandGenerationFunctions.RandFunction2_Double;
-import com.oracle.truffle.r.library.stats.RandGenerationFunctions.RandomNumberProvider;
-import com.oracle.truffle.r.library.stats.StatsFunctions.Function3_1;
-import com.oracle.truffle.r.library.stats.StatsFunctions.Function3_2;
+package com.oracle.truffle.r.runtime.nmath.distr;
+
+import com.oracle.truffle.r.runtime.nmath.DPQ;
+import com.oracle.truffle.r.runtime.nmath.DPQ.EarlyReturn;
+import com.oracle.truffle.r.runtime.nmath.MathFunctions.Function3_1;
+import com.oracle.truffle.r.runtime.nmath.MathFunctions.Function3_2;
+import com.oracle.truffle.r.runtime.nmath.RMath;
+import com.oracle.truffle.r.runtime.nmath.RMathError;
+import com.oracle.truffle.r.runtime.nmath.RandomFunctions.RandFunction2_Double;
+import com.oracle.truffle.r.runtime.nmath.RandomFunctions.RandomNumberProvider;
+import com.oracle.truffle.r.runtime.nmath.TOMS708;
 
 public final class Logis {
     private Logis() {
diff --git a/com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/stats/PGamma.java b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/nmath/distr/PGamma.java
similarity index 75%
rename from com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/stats/PGamma.java
rename to com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/nmath/distr/PGamma.java
index 5886a01b16..e939bbdc1b 100644
--- a/com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/stats/PGamma.java
+++ b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/nmath/distr/PGamma.java
@@ -6,15 +6,17 @@
  * Copyright (C) 2005-6 Morten Welinder <terra@gnome.org>
  * Copyright (C) 2005-10 The R Foundation
  * Copyright (C) 2006-2015 The R Core Team
- * Copyright (c) 2016, Oracle and/or its affiliates
+ * Copyright (c) 2016, 2017, Oracle and/or its affiliates
  *
  * All rights reserved.
  */
-package com.oracle.truffle.r.library.stats;
+package com.oracle.truffle.r.runtime.nmath.distr;
 
-import static com.oracle.truffle.r.library.stats.GammaFunctions.pgammaRaw;
+import static com.oracle.truffle.r.runtime.nmath.GammaFunctions.pgammaRaw;
 
-import com.oracle.truffle.r.library.stats.StatsFunctions.Function3_2;
+import com.oracle.truffle.r.runtime.nmath.DPQ;
+import com.oracle.truffle.r.runtime.nmath.MathFunctions.Function3_2;
+import com.oracle.truffle.r.runtime.nmath.RMathError;
 
 public final class PGamma implements Function3_2 {
     @Override
diff --git a/com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/stats/PHyper.java b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/nmath/distr/PHyper.java
similarity index 87%
rename from com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/stats/PHyper.java
rename to com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/nmath/distr/PHyper.java
index 5a6922a91a..28bcd2a42f 100644
--- a/com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/stats/PHyper.java
+++ b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/nmath/distr/PHyper.java
@@ -6,7 +6,7 @@
  * Copyright (C) 1998 Ross Ihaka
  * Copyright (c) 1999-2014, The R Core Team
  * Copyright (c) 2004, The R Foundation
- * Copyright (c) 2016, Oracle and/or its affiliates
+ * Copyright (c) 2016, 2017, Oracle and/or its affiliates
  *
  * All rights reserved.
  */
@@ -19,11 +19,14 @@
  * Subject: [Rd] phyper accuracy and efficiency (PR#6772)
  * Date: Thu, 15 Apr 2004 18:06:37 +0200 (CEST)
  */
-package com.oracle.truffle.r.library.stats;
+package com.oracle.truffle.r.runtime.nmath.distr;
 
-import static com.oracle.truffle.r.library.stats.MathConstants.DBL_EPSILON;
+import static com.oracle.truffle.r.runtime.nmath.MathConstants.DBL_EPSILON;
 
-import com.oracle.truffle.r.library.stats.StatsFunctions.Function4_2;
+import com.oracle.truffle.r.runtime.nmath.DPQ;
+import com.oracle.truffle.r.runtime.nmath.MathFunctions.Function4_2;
+import com.oracle.truffle.r.runtime.nmath.RMath;
+import com.oracle.truffle.r.runtime.nmath.RMathError;
 
 public final class PHyper implements Function4_2 {
     private final DHyper dhyper = new DHyper();
diff --git a/com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/stats/PNBeta.java b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/nmath/distr/PNBeta.java
similarity index 87%
rename from com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/stats/PNBeta.java
rename to com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/nmath/distr/PNBeta.java
index 012c7b2b16..1cbea63b51 100644
--- a/com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/stats/PNBeta.java
+++ b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/nmath/distr/PNBeta.java
@@ -4,18 +4,21 @@
  * http://www.gnu.org/licenses/gpl-2.0.html
  *
  * Copyright (c) 2000-2013, The R Core Team
- * Copyright (c) 2016, Oracle and/or its affiliates
+ * Copyright (c) 2016, 2017, Oracle and/or its affiliates
  *
  * All rights reserved.
  */
-package com.oracle.truffle.r.library.stats;
+package com.oracle.truffle.r.runtime.nmath.distr;
 
-import static com.oracle.truffle.r.library.stats.GammaFunctions.lgammafn;
+import static com.oracle.truffle.r.runtime.nmath.GammaFunctions.lgammafn;
 
-import com.oracle.truffle.r.library.stats.DPQ.EarlyReturn;
-import com.oracle.truffle.r.library.stats.RMathError.MLError;
-import com.oracle.truffle.r.library.stats.StatsFunctions.Function4_2;
-import com.oracle.truffle.r.library.stats.TOMS708.Bratio;
+import com.oracle.truffle.r.runtime.nmath.DPQ;
+import com.oracle.truffle.r.runtime.nmath.DPQ.EarlyReturn;
+import com.oracle.truffle.r.runtime.nmath.MathFunctions.Function4_2;
+import com.oracle.truffle.r.runtime.nmath.RMath;
+import com.oracle.truffle.r.runtime.nmath.RMathError;
+import com.oracle.truffle.r.runtime.nmath.RMathError.MLError;
+import com.oracle.truffle.r.runtime.nmath.TOMS708.Bratio;
 
 public final class PNBeta implements Function4_2 {
     @Override
diff --git a/com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/stats/PNBinom.java b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/nmath/distr/PNBinom.java
similarity index 90%
rename from com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/stats/PNBinom.java
rename to com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/nmath/distr/PNBinom.java
index 7a45673c6c..e477f9601b 100644
--- a/com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/stats/PNBinom.java
+++ b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/nmath/distr/PNBinom.java
@@ -5,16 +5,18 @@
  *
  * Copyright (C) 1998 Ross Ihaka
  * Copyright (c) 2000-2016, The R Core Team
- * Copyright (c) 2016, Oracle and/or its affiliates
+ * Copyright (c) 2016, 2017, Oracle and/or its affiliates
  *
  * All rights reserved.
  */
-package com.oracle.truffle.r.library.stats;
+package com.oracle.truffle.r.runtime.nmath.distr;
 
-import com.oracle.truffle.r.library.stats.StatsFunctions.Function3_2;
-import com.oracle.truffle.r.library.stats.TOMS708.Bratio;
 import com.oracle.truffle.r.runtime.RError.Message;
 import com.oracle.truffle.r.runtime.Utils;
+import com.oracle.truffle.r.runtime.nmath.DPQ;
+import com.oracle.truffle.r.runtime.nmath.MathFunctions.Function3_2;
+import com.oracle.truffle.r.runtime.nmath.RMathError;
+import com.oracle.truffle.r.runtime.nmath.TOMS708.Bratio;
 
 public final class PNBinom {
     private PNBinom() {
diff --git a/com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/stats/PNChisq.java b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/nmath/distr/PNChisq.java
similarity index 91%
rename from com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/stats/PNChisq.java
rename to com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/nmath/distr/PNChisq.java
index c776e2c447..817566420a 100644
--- a/com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/stats/PNChisq.java
+++ b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/nmath/distr/PNChisq.java
@@ -5,7 +5,7 @@
  *
  * Copyright (c) 2000-2015, The R Core Team
  * Copyright (c) 2003-2015, The R Foundation
- * Copyright (c) 2016, Oracle and/or its affiliates
+ * Copyright (c) 2016, 2017, Oracle and/or its affiliates
  *
  * All rights reserved.
  */
@@ -22,21 +22,24 @@
  *    distribution function. Appl.Statist., 41, 478-482.
  */
 
-package com.oracle.truffle.r.library.stats;
+package com.oracle.truffle.r.runtime.nmath.distr;
 
-import static com.oracle.truffle.r.library.stats.GammaFunctions.lgamma;
-import static com.oracle.truffle.r.library.stats.GammaFunctions.lgammafn;
-import static com.oracle.truffle.r.library.stats.MathConstants.DBL_EPSILON;
-import static com.oracle.truffle.r.library.stats.MathConstants.DBL_MIN_EXP;
-import static com.oracle.truffle.r.library.stats.MathConstants.M_LN10;
-import static com.oracle.truffle.r.library.stats.MathConstants.M_LN2;
-import static com.oracle.truffle.r.library.stats.MathConstants.M_LN_SQRT_2PI;
-import static com.oracle.truffle.r.library.stats.MathConstants.logspaceAdd;
+import static com.oracle.truffle.r.runtime.nmath.GammaFunctions.lgamma;
+import static com.oracle.truffle.r.runtime.nmath.GammaFunctions.lgammafn;
+import static com.oracle.truffle.r.runtime.nmath.MathConstants.DBL_EPSILON;
+import static com.oracle.truffle.r.runtime.nmath.MathConstants.DBL_MIN_EXP;
+import static com.oracle.truffle.r.runtime.nmath.MathConstants.M_LN10;
+import static com.oracle.truffle.r.runtime.nmath.MathConstants.M_LN2;
+import static com.oracle.truffle.r.runtime.nmath.MathConstants.M_LN_SQRT_2PI;
+import static com.oracle.truffle.r.runtime.nmath.MathConstants.logspaceAdd;
 
-import com.oracle.truffle.r.library.stats.Chisq.PChisq;
-import com.oracle.truffle.r.library.stats.RMathError.MLError;
-import com.oracle.truffle.r.library.stats.StatsFunctions.Function3_2;
 import com.oracle.truffle.r.runtime.RError.Message;
+import com.oracle.truffle.r.runtime.nmath.DPQ;
+import com.oracle.truffle.r.runtime.nmath.MathFunctions.Function3_2;
+import com.oracle.truffle.r.runtime.nmath.RMath;
+import com.oracle.truffle.r.runtime.nmath.RMathError;
+import com.oracle.truffle.r.runtime.nmath.RMathError.MLError;
+import com.oracle.truffle.r.runtime.nmath.distr.Chisq.PChisq;
 
 public final class PNChisq implements Function3_2 {
     private static final double _dbl_min_exp = M_LN2 * DBL_MIN_EXP;
@@ -290,7 +293,7 @@ public final class PNChisq implements Function3_2 {
     }
 
     /**
-     * For easier switch to {@code Decimal} if necessary.
+     * For easier switch to some variant of {@code long double} if necessary.
      */
     private static final class MathWrapper {
         public static double exp(double x) {
diff --git a/com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/stats/PPois.java b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/nmath/distr/PPois.java
similarity index 73%
rename from com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/stats/PPois.java
rename to com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/nmath/distr/PPois.java
index 1ad3492f1f..2bf05cb036 100644
--- a/com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/stats/PPois.java
+++ b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/nmath/distr/PPois.java
@@ -5,15 +5,17 @@
  *
  * Copyright (C) 1998 Ross Ihaka
  * Copyright (c) 2000, The R Core Team
- * Copyright (c) 2016, Oracle and/or its affiliates
+ * Copyright (c) 2016, 2017, Oracle and/or its affiliates
  *
  * All rights reserved.
  */
-package com.oracle.truffle.r.library.stats;
+package com.oracle.truffle.r.runtime.nmath.distr;
 
-import static com.oracle.truffle.r.library.stats.GammaFunctions.pgamma;
+import static com.oracle.truffle.r.runtime.nmath.GammaFunctions.pgamma;
 
-import com.oracle.truffle.r.library.stats.StatsFunctions.Function2_2;
+import com.oracle.truffle.r.runtime.nmath.DPQ;
+import com.oracle.truffle.r.runtime.nmath.MathFunctions.Function2_2;
+import com.oracle.truffle.r.runtime.nmath.RMathError;
 
 public final class PPois implements Function2_2 {
     @Override
diff --git a/com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/stats/Pbeta.java b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/nmath/distr/Pbeta.java
similarity index 90%
rename from com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/stats/Pbeta.java
rename to com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/nmath/distr/Pbeta.java
index c195a4bbc2..4e0c3764fa 100644
--- a/com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/stats/Pbeta.java
+++ b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/nmath/distr/Pbeta.java
@@ -8,13 +8,16 @@
  *
  * All rights reserved.
  */
-package com.oracle.truffle.r.library.stats;
+package com.oracle.truffle.r.runtime.nmath.distr;
 
 import com.oracle.truffle.api.CompilerDirectives.TruffleBoundary;
 import com.oracle.truffle.api.profiles.BranchProfile;
-import com.oracle.truffle.r.library.stats.StatsFunctions.Function3_2;
-import com.oracle.truffle.r.library.stats.TOMS708.Bratio;
 import com.oracle.truffle.r.runtime.RError.Message;
+import com.oracle.truffle.r.runtime.nmath.DPQ;
+import com.oracle.truffle.r.runtime.nmath.MathConstants;
+import com.oracle.truffle.r.runtime.nmath.MathFunctions.Function3_2;
+import com.oracle.truffle.r.runtime.nmath.RMathError;
+import com.oracle.truffle.r.runtime.nmath.TOMS708.Bratio;
 
 // transcribed from pbeta.c
 
diff --git a/com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/stats/Pbinom.java b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/nmath/distr/Pbinom.java
similarity index 80%
rename from com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/stats/Pbinom.java
rename to com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/nmath/distr/Pbinom.java
index f0b796a884..e4ec6ad387 100644
--- a/com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/stats/Pbinom.java
+++ b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/nmath/distr/Pbinom.java
@@ -6,15 +6,19 @@
  * Copyright (C) 1998 Ross Ihaka
  * Copyright (c) 2000--2014, The R Core Team
  * Copyright (c) 2007, The R Foundation
- * Copyright (c) 2016, 2016, Oracle and/or its affiliates
+ * Copyright (c) 2016, 2017, Oracle and/or its affiliates
  *
  * All rights reserved.
  */
-package com.oracle.truffle.r.library.stats;
+package com.oracle.truffle.r.runtime.nmath.distr;
 
 import com.oracle.truffle.api.profiles.BranchProfile;
+import com.oracle.truffle.r.runtime.nmath.DPQ;
+import com.oracle.truffle.r.runtime.nmath.MathFunctions.Function3_2;
+import com.oracle.truffle.r.runtime.nmath.RMath;
+import com.oracle.truffle.r.runtime.nmath.RMathError;
 
-public final class Pbinom implements StatsFunctions.Function3_2 {
+public final class Pbinom implements Function3_2 {
 
     private final BranchProfile nanProfile = BranchProfile.create();
 
diff --git a/com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/stats/Pf.java b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/nmath/distr/Pf.java
similarity index 81%
rename from com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/stats/Pf.java
rename to com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/nmath/distr/Pf.java
index f595cf1cc3..1cf70dd836 100644
--- a/com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/stats/Pf.java
+++ b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/nmath/distr/Pf.java
@@ -5,19 +5,22 @@
  *
  * Copyright (C) 1998 Ross Ihaka
  * Copyright (c) 1998--2008, The R Core Team
- * Copyright (c) 2016, 2016, Oracle and/or its affiliates
+ * Copyright (c) 2016, 2017, Oracle and/or its affiliates
  *
  * All rights reserved.
  */
-package com.oracle.truffle.r.library.stats;
+package com.oracle.truffle.r.runtime.nmath.distr;
 
-import static com.oracle.truffle.r.library.stats.DPQ.rdt0;
-import static com.oracle.truffle.r.library.stats.DPQ.rdt1;
+import static com.oracle.truffle.r.runtime.nmath.DPQ.rdt0;
+import static com.oracle.truffle.r.runtime.nmath.DPQ.rdt1;
 
 import com.oracle.truffle.api.profiles.BranchProfile;
+import com.oracle.truffle.r.runtime.nmath.GammaFunctions;
+import com.oracle.truffle.r.runtime.nmath.MathConstants;
+import com.oracle.truffle.r.runtime.nmath.MathFunctions.Function3_2;
 
 // transcribed from nmath/pf.c
-public final class Pf implements StatsFunctions.Function3_2 {
+public final class Pf implements Function3_2 {
 
     private final BranchProfile nanProfile = BranchProfile.create();
 
diff --git a/com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/stats/Pnf.java b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/nmath/distr/Pnf.java
similarity index 82%
rename from com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/stats/Pnf.java
rename to com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/nmath/distr/Pnf.java
index a48d487b9d..a1e22e8dcb 100644
--- a/com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/stats/Pnf.java
+++ b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/nmath/distr/Pnf.java
@@ -5,14 +5,16 @@
  *
  * Copyright (C) 1998 Ross Ihaka
  * Copyright (c) 2000-2008, The R Core Team
- * Copyright (c) 2016, Oracle and/or its affiliates
+ * Copyright (c) 2016, 2017, Oracle and/or its affiliates
  *
  * All rights reserved.
  */
-package com.oracle.truffle.r.library.stats;
+package com.oracle.truffle.r.runtime.nmath.distr;
 
-import com.oracle.truffle.r.library.stats.DPQ.EarlyReturn;
-import com.oracle.truffle.r.library.stats.StatsFunctions.Function4_2;
+import com.oracle.truffle.r.runtime.nmath.DPQ;
+import com.oracle.truffle.r.runtime.nmath.DPQ.EarlyReturn;
+import com.oracle.truffle.r.runtime.nmath.MathFunctions.Function4_2;
+import com.oracle.truffle.r.runtime.nmath.RMathError;
 
 public final class Pnf implements Function4_2 {
     private final PNChisq pnchisq = new PNChisq();
diff --git a/com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/stats/Pnorm.java b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/nmath/distr/Pnorm.java
similarity index 97%
rename from com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/stats/Pnorm.java
rename to com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/nmath/distr/Pnorm.java
index bc15917ca0..bf069e9a01 100644
--- a/com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/stats/Pnorm.java
+++ b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/nmath/distr/Pnorm.java
@@ -10,14 +10,17 @@
  *
  * All rights reserved.
  */
-package com.oracle.truffle.r.library.stats;
+package com.oracle.truffle.r.runtime.nmath.distr;
 
 import com.oracle.truffle.api.profiles.BranchProfile;
 import com.oracle.truffle.r.runtime.RRuntime;
+import com.oracle.truffle.r.runtime.nmath.DPQ;
+import com.oracle.truffle.r.runtime.nmath.MathConstants;
+import com.oracle.truffle.r.runtime.nmath.MathFunctions.Function3_2;
 
 // transcribed from pnorm.c
 
-public final class Pnorm implements StatsFunctions.Function3_2 {
+public final class Pnorm implements Function3_2 {
 
     private final BranchProfile nanProfile = BranchProfile.create();
 
diff --git a/com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/stats/Pt.java b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/nmath/distr/Pt.java
similarity index 78%
rename from com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/stats/Pt.java
rename to com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/nmath/distr/Pt.java
index f1ef9bf8a5..142b3e0f1e 100644
--- a/com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/stats/Pt.java
+++ b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/nmath/distr/Pt.java
@@ -5,18 +5,20 @@
  *
  * Copyright (c) 1995, 1996, Robert Gentleman and Ross Ihaka
  * Copyright (c) 2000-2007, The R Core Team
- * Copyright (c) 2016, Oracle and/or its affiliates
+ * Copyright (c) 2016, 2017, Oracle and/or its affiliates
  *
  * All rights reserved.
  */
-package com.oracle.truffle.r.library.stats;
+package com.oracle.truffle.r.runtime.nmath.distr;
 
-import static com.oracle.truffle.r.library.stats.LBeta.lbeta;
-import static com.oracle.truffle.r.library.stats.MathConstants.M_LN2;
-import static com.oracle.truffle.r.library.stats.Pbeta.pbeta;
+import static com.oracle.truffle.r.runtime.nmath.LBeta.lbeta;
+import static com.oracle.truffle.r.runtime.nmath.MathConstants.M_LN2;
 
 import com.oracle.truffle.api.profiles.BranchProfile;
-import com.oracle.truffle.r.library.stats.StatsFunctions.Function2_2;
+import com.oracle.truffle.r.runtime.nmath.DPQ;
+import com.oracle.truffle.r.runtime.nmath.MathFunctions.Function2_2;
+import com.oracle.truffle.r.runtime.nmath.RMath;
+import com.oracle.truffle.r.runtime.nmath.RMathError;
 
 public final class Pt implements Function2_2 {
     private final BranchProfile pbetaNanProfile = BranchProfile.create();
@@ -61,8 +63,8 @@ public final class Pt implements Function2_2 {
             val = logP ? lval : Math.exp(lval);
         } else {
             val = (n > x * x)
-                            ? pbeta(x * x / (n + x * x), 0.5, n / 2., /* lower_tail */false, logP, pbetaNanProfile)
-                            : pbeta(1. / nx, n / 2., 0.5, /* lower_tail */true, logP, pbetaNanProfile);
+                            ? Pbeta.pbeta(x * x / (n + x * x), 0.5, n / 2., /* lower_tail */false, logP, pbetaNanProfile)
+                            : Pbeta.pbeta(1. / nx, n / 2., 0.5, /* lower_tail */true, logP, pbetaNanProfile);
         }
 
         /* Use "1 - v" if lower_tail and x > 0 (but not both): */
diff --git a/com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/stats/QBeta.java b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/nmath/distr/QBeta.java
similarity index 96%
rename from com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/stats/QBeta.java
rename to com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/nmath/distr/QBeta.java
index ce7e709e31..02e634aff2 100644
--- a/com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/stats/QBeta.java
+++ b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/nmath/distr/QBeta.java
@@ -19,21 +19,23 @@
  * Remark AS R83 (v.39, 309-310) and the correction (v.40(1) p.236)
  *      have been incorporated in this version.
  */
-package com.oracle.truffle.r.library.stats;
+package com.oracle.truffle.r.runtime.nmath.distr;
 
-import static com.oracle.truffle.r.library.stats.Arithmetic.powDi;
-import static com.oracle.truffle.r.library.stats.LBeta.lbeta;
-import static com.oracle.truffle.r.library.stats.MathConstants.DBL_MANT_DIG;
-import static com.oracle.truffle.r.library.stats.MathConstants.DBL_MIN;
-import static com.oracle.truffle.r.library.stats.MathConstants.DBL_MIN_EXP;
-import static com.oracle.truffle.r.library.stats.MathConstants.ML_NAN;
-import static com.oracle.truffle.r.library.stats.MathConstants.M_LN2;
-import static com.oracle.truffle.r.library.stats.Pbeta.pbetaRaw;
+import static com.oracle.truffle.r.runtime.nmath.Arithmetic.powDi;
+import static com.oracle.truffle.r.runtime.nmath.LBeta.lbeta;
+import static com.oracle.truffle.r.runtime.nmath.MathConstants.DBL_MANT_DIG;
+import static com.oracle.truffle.r.runtime.nmath.MathConstants.DBL_MIN;
+import static com.oracle.truffle.r.runtime.nmath.MathConstants.DBL_MIN_EXP;
+import static com.oracle.truffle.r.runtime.nmath.MathConstants.ML_NAN;
+import static com.oracle.truffle.r.runtime.nmath.MathConstants.M_LN2;
 
 import com.oracle.truffle.api.CompilerDirectives.TruffleBoundary;
-import com.oracle.truffle.r.library.stats.RMathError.MLError;
-import com.oracle.truffle.r.library.stats.StatsFunctions.Function3_2;
 import com.oracle.truffle.r.runtime.RError.Message;
+import com.oracle.truffle.r.runtime.nmath.DPQ;
+import com.oracle.truffle.r.runtime.nmath.MathFunctions.Function3_2;
+import com.oracle.truffle.r.runtime.nmath.RMath;
+import com.oracle.truffle.r.runtime.nmath.RMathError;
+import com.oracle.truffle.r.runtime.nmath.RMathError.MLError;
 
 public final class QBeta implements Function3_2 {
     private static final double USE_LOG_X_CUTOFF = -5.;
@@ -379,7 +381,7 @@ public final class QBeta implements Function3_2 {
                                            * e.g. qbeta(0.21, .001, 0.05) try "left border" quickly,
                                            * i.e., try at smallest positive number:
                                            */
-                w = pbetaRaw(DBL_very_MIN, pp, qq, true, log_p);
+                w = Pbeta.pbetaRaw(DBL_very_MIN, pp, qq, true, log_p);
                 if (w > (log_p ? la : a)) {
                     debugPrintf(" quantile is left of smallest positive number; \"convergence\"\n");
                     if (log_p || Math.abs(w - a) < Math.abs(0 - a)) { // DBL_very_MIN is better than
@@ -445,7 +447,7 @@ public final class QBeta implements Function3_2 {
                     // using log_p == true unconditionally here
                     // FIXME: if Math.exp(u) = xinbta underflows to 0, like different formula
                     // pbeta_Math.log(u, *)
-                    y = pbetaRaw(xinbta, pp, qq, /* lower_tail = */ true, true);
+                    y = Pbeta.pbetaRaw(xinbta, pp, qq, /* lower_tail = */ true, true);
 
                     /*
                      * w := Newton step size for L(u) = log F(e^u) =!= 0; u := Math.log(x) = (L(.) -
@@ -503,7 +505,7 @@ public final class QBeta implements Function3_2 {
 
             } else {
                 for (int i_pb = 0; i_pb < 1000; i_pb++) {
-                    y = pbetaRaw(xinbta, pp, qq, /* lower_tail = */ true, log_p);
+                    y = Pbeta.pbetaRaw(xinbta, pp, qq, /* lower_tail = */ true, log_p);
                     // delta{y} : d_y = y - (log_p ? la : a);
 
                     if (!Double.isFinite(y) && !(log_p && y == Double.NEGATIVE_INFINITY)) { // y =
@@ -574,7 +576,7 @@ public final class QBeta implements Function3_2 {
                             y - (log_ ? la : a), (log_ ? " (log_)" : ""));
             if ((log_ && y == Double.NEGATIVE_INFINITY) || (!log_ && y == 0)) {
                 // stuck at left, try if smallest positive number is "better"
-                w = pbetaRaw(DBL_very_MIN, pp, qq, true, log_);
+                w = Pbeta.pbetaRaw(DBL_very_MIN, pp, qq, true, log_);
                 if (log_ || Math.abs(w - a) <= Math.abs(y - a)) {
                     tx = DBL_very_MIN;
                     u_n = DBL_log_v_MIN; // = Math.log(DBL_very_MIN)
@@ -585,7 +587,7 @@ public final class QBeta implements Function3_2 {
                                 // e.g. qbeta(-1e-10, .2, .03, log=true) cannot get accurate ==> do
                                 // NOT
                                 // warn
-                                pbetaRaw(DBL_1__eps, // = 1 - eps
+                                Pbeta.pbetaRaw(DBL_1__eps, // = 1 - eps
                                                 pp, qq, true, true) > la + 2)) {
                     RMathError.warning(Message.QBETA_ACURACY_WARNING, (log_ ? ", log_" : ""), Math.abs(y - (log_ ? la : a)));
                 }
@@ -616,7 +618,7 @@ public final class QBeta implements Function3_2 {
                          * 0.125, 2^-96)
                          */
                         double tmpXinbta = Math.exp(u_n);
-                        y = pbetaRaw(tmpXinbta, pp, qq, /* lower_tail = */ true, log_p);
+                        y = Pbeta.pbetaRaw(tmpXinbta, pp, qq, /* lower_tail = */ true, log_p);
                         w = log_p
                                         ? (y - la) * Math.exp(y + logbeta + r * Math.log(tmpXinbta) + t * RMath.log1p(-tmpXinbta))
                                         : (y - a) * Math.exp(logbeta + r * Math.log(tmpXinbta) + t * RMath.log1p(-tmpXinbta));
diff --git a/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/nmath/distr/QGamma.java b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/nmath/distr/QGamma.java
new file mode 100644
index 0000000000..ef4ba66143
--- /dev/null
+++ b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/nmath/distr/QGamma.java
@@ -0,0 +1,33 @@
+/*
+ * Copyright (c) 2017, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package com.oracle.truffle.r.runtime.nmath.distr;
+
+import com.oracle.truffle.r.runtime.nmath.GammaFunctions;
+import com.oracle.truffle.r.runtime.nmath.MathFunctions.Function3_2;
+
+public final class QGamma implements Function3_2 {
+    @Override
+    public double evaluate(double p, double shape, double scale, boolean lowerTail, boolean logP) {
+        return GammaFunctions.qgamma(p, shape, scale, lowerTail, logP);
+    }
+}
diff --git a/com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/stats/QHyper.java b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/nmath/distr/QHyper.java
similarity index 81%
rename from com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/stats/QHyper.java
rename to com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/nmath/distr/QHyper.java
index 727442b4a6..e038d3ea0c 100644
--- a/com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/stats/QHyper.java
+++ b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/nmath/distr/QHyper.java
@@ -5,20 +5,22 @@
  *
  * Copyright (C) 1998 Ross Ihaka
  * Copyright (c) 2000--2014, The R Core Team
- * Copyright (c) 2016, Oracle and/or its affiliates
+ * Copyright (c) 2016, 2017, Oracle and/or its affiliates
  *
  * All rights reserved.
  */
-package com.oracle.truffle.r.library.stats;
+package com.oracle.truffle.r.runtime.nmath.distr;
 
-import static com.oracle.truffle.r.library.stats.MathConstants.DBL_EPSILON;
-import static com.oracle.truffle.r.library.stats.RMath.fmax2;
-import static com.oracle.truffle.r.library.stats.RMath.fmin2;
-import static com.oracle.truffle.r.library.stats.RMath.forceint;
-import static com.oracle.truffle.r.library.stats.RMath.lfastchoose;
+import static com.oracle.truffle.r.runtime.nmath.Choose.lfastchoose;
+import static com.oracle.truffle.r.runtime.nmath.MathConstants.DBL_EPSILON;
+import static com.oracle.truffle.r.runtime.nmath.RMath.fmax2;
+import static com.oracle.truffle.r.runtime.nmath.RMath.fmin2;
+import static com.oracle.truffle.r.runtime.nmath.RMath.forceint;
 
-import com.oracle.truffle.r.library.stats.DPQ.EarlyReturn;
-import com.oracle.truffle.r.library.stats.StatsFunctions.Function4_2;
+import com.oracle.truffle.r.runtime.nmath.DPQ;
+import com.oracle.truffle.r.runtime.nmath.DPQ.EarlyReturn;
+import com.oracle.truffle.r.runtime.nmath.MathFunctions.Function4_2;
+import com.oracle.truffle.r.runtime.nmath.RMathError;
 
 public final class QHyper implements Function4_2 {
     @Override
diff --git a/com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/stats/QNBeta.java b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/nmath/distr/QNBeta.java
similarity index 79%
rename from com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/stats/QNBeta.java
rename to com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/nmath/distr/QNBeta.java
index ccbd2f19b1..bf7e7992fe 100644
--- a/com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/stats/QNBeta.java
+++ b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/nmath/distr/QNBeta.java
@@ -4,17 +4,20 @@
  * http://www.gnu.org/licenses/gpl-2.0.html
  *
  * Copyright (c) 2006, The R Core Team
- * Copyright (c) 2016, Oracle and/or its affiliates
+ * Copyright (c) 2016, 2017, Oracle and/or its affiliates
  *
  * All rights reserved.
  */
-package com.oracle.truffle.r.library.stats;
+package com.oracle.truffle.r.runtime.nmath.distr;
 
-import static com.oracle.truffle.r.library.stats.MathConstants.DBL_EPSILON;
-import static com.oracle.truffle.r.library.stats.MathConstants.DBL_MIN;
+import static com.oracle.truffle.r.runtime.nmath.MathConstants.DBL_EPSILON;
+import static com.oracle.truffle.r.runtime.nmath.MathConstants.DBL_MIN;
 
-import com.oracle.truffle.r.library.stats.DPQ.EarlyReturn;
-import com.oracle.truffle.r.library.stats.StatsFunctions.Function4_2;
+import com.oracle.truffle.r.runtime.nmath.DPQ;
+import com.oracle.truffle.r.runtime.nmath.DPQ.EarlyReturn;
+import com.oracle.truffle.r.runtime.nmath.MathFunctions.Function4_2;
+import com.oracle.truffle.r.runtime.nmath.RMath;
+import com.oracle.truffle.r.runtime.nmath.RMathError;
 
 public final class QNBeta implements Function4_2 {
     private static final double accu = 1e-15;
diff --git a/com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/stats/QNBinom.java b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/nmath/distr/QNBinom.java
similarity index 88%
rename from com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/stats/QNBinom.java
rename to com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/nmath/distr/QNBinom.java
index c568e6e006..2407bc03b8 100644
--- a/com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/stats/QNBinom.java
+++ b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/nmath/distr/QNBinom.java
@@ -6,17 +6,20 @@
  * Copyright (C) 1998 Ross Ihaka
  * Copyright (c) 2000-2016, The R Core Team
  * Copyright (c) 2005-2016, The R Foundation
- * Copyright (c) 2016, Oracle and/or its affiliates
+ * Copyright (c) 2016, 2017, Oracle and/or its affiliates
  *
  * All rights reserved.
  */
-package com.oracle.truffle.r.library.stats;
+package com.oracle.truffle.r.runtime.nmath.distr;
 
-import static com.oracle.truffle.r.library.stats.MathConstants.DBL_EPSILON;
+import static com.oracle.truffle.r.runtime.nmath.MathConstants.DBL_EPSILON;
 
-import com.oracle.truffle.r.library.stats.DPQ.EarlyReturn;
-import com.oracle.truffle.r.library.stats.PNBinom.PNBinomFunc;
-import com.oracle.truffle.r.library.stats.StatsFunctions.Function3_2;
+import com.oracle.truffle.r.runtime.nmath.DPQ;
+import com.oracle.truffle.r.runtime.nmath.DPQ.EarlyReturn;
+import com.oracle.truffle.r.runtime.nmath.MathFunctions.Function3_2;
+import com.oracle.truffle.r.runtime.nmath.RMath;
+import com.oracle.truffle.r.runtime.nmath.RMathError;
+import com.oracle.truffle.r.runtime.nmath.distr.PNBinom.PNBinomFunc;
 
 public final class QNBinom {
     private QNBinom() {
diff --git a/com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/stats/QNChisq.java b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/nmath/distr/QNChisq.java
similarity index 84%
rename from com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/stats/QNChisq.java
rename to com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/nmath/distr/QNChisq.java
index 6673c76ce1..45ca7537a4 100644
--- a/com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/stats/QNChisq.java
+++ b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/nmath/distr/QNChisq.java
@@ -6,20 +6,23 @@
  * Copyright (c) 1995, 1996  Robert Gentleman and Ross Ihaka
  * Copyright (c) 2000-2008, The R Core Team
  * Copyright (c) 2004, The R Foundation
- * Copyright (c) 2016, Oracle and/or its affiliates
+ * Copyright (c) 2016, 2017, Oracle and/or its affiliates
  *
  * All rights reserved.
  */
-package com.oracle.truffle.r.library.stats;
+package com.oracle.truffle.r.runtime.nmath.distr;
 
-import static com.oracle.truffle.r.library.stats.MathConstants.DBL_EPSILON;
-import static com.oracle.truffle.r.library.stats.MathConstants.DBL_MAX;
-import static com.oracle.truffle.r.library.stats.MathConstants.DBL_MIN;
+import static com.oracle.truffle.r.runtime.nmath.MathConstants.DBL_EPSILON;
+import static com.oracle.truffle.r.runtime.nmath.MathConstants.DBL_MAX;
+import static com.oracle.truffle.r.runtime.nmath.MathConstants.DBL_MIN;
 
-import com.oracle.truffle.r.library.stats.Chisq.QChisq;
-import com.oracle.truffle.r.library.stats.DPQ.EarlyReturn;
-import com.oracle.truffle.r.library.stats.RMathError.MLError;
-import com.oracle.truffle.r.library.stats.StatsFunctions.Function3_2;
+import com.oracle.truffle.r.runtime.nmath.DPQ;
+import com.oracle.truffle.r.runtime.nmath.DPQ.EarlyReturn;
+import com.oracle.truffle.r.runtime.nmath.MathFunctions.Function3_2;
+import com.oracle.truffle.r.runtime.nmath.RMath;
+import com.oracle.truffle.r.runtime.nmath.RMathError;
+import com.oracle.truffle.r.runtime.nmath.RMathError.MLError;
+import com.oracle.truffle.r.runtime.nmath.distr.Chisq.QChisq;
 
 public final class QNChisq implements Function3_2 {
     private static final double accu = 1e-13;
diff --git a/com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/stats/QPois.java b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/nmath/distr/QPois.java
similarity index 85%
rename from com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/stats/QPois.java
rename to com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/nmath/distr/QPois.java
index ff6ee1915e..e3f29bdeb6 100644
--- a/com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/stats/QPois.java
+++ b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/nmath/distr/QPois.java
@@ -5,16 +5,19 @@
  *
  * Copyright (C) 1998 Ross Ihaka
  * Copyright (c) 2000-2014, The R Core Team
- * Copyright (c) 2016, Oracle and/or its affiliates
+ * Copyright (c) 2016, 2017, Oracle and/or its affiliates
  *
  * All rights reserved.
  */
-package com.oracle.truffle.r.library.stats;
+package com.oracle.truffle.r.runtime.nmath.distr;
 
-import static com.oracle.truffle.r.library.stats.MathConstants.DBL_EPSILON;
+import static com.oracle.truffle.r.runtime.nmath.MathConstants.DBL_EPSILON;
 
-import com.oracle.truffle.r.library.stats.DPQ.EarlyReturn;
-import com.oracle.truffle.r.library.stats.StatsFunctions.Function2_2;
+import com.oracle.truffle.r.runtime.nmath.DPQ;
+import com.oracle.truffle.r.runtime.nmath.DPQ.EarlyReturn;
+import com.oracle.truffle.r.runtime.nmath.MathFunctions.Function2_2;
+import com.oracle.truffle.r.runtime.nmath.RMath;
+import com.oracle.truffle.r.runtime.nmath.RMathError;
 
 public final class QPois implements Function2_2 {
     private final Qnorm qnorm = new Qnorm();
diff --git a/com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/stats/Qbinom.java b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/nmath/distr/Qbinom.java
similarity index 91%
rename from com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/stats/Qbinom.java
rename to com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/nmath/distr/Qbinom.java
index a11cdcb201..9fa08bedc9 100644
--- a/com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/stats/Qbinom.java
+++ b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/nmath/distr/Qbinom.java
@@ -6,19 +6,21 @@
  * 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
+ * Copyright (c) 2016, 2017, Oracle and/or its affiliates
  *
  * All rights reserved.
  */
-package com.oracle.truffle.r.library.stats;
+package com.oracle.truffle.r.runtime.nmath.distr;
 
 import com.oracle.truffle.api.profiles.BranchProfile;
 import com.oracle.truffle.api.profiles.ConditionProfile;
 import com.oracle.truffle.r.runtime.RRuntime;
+import com.oracle.truffle.r.runtime.nmath.DPQ;
+import com.oracle.truffle.r.runtime.nmath.MathFunctions.Function3_2;
 
 // transcribed from qbinom.c
 
-public final class Qbinom implements StatsFunctions.Function3_2 {
+public final class Qbinom implements Function3_2 {
     private final BranchProfile nanProfile = BranchProfile.create();
     private final ConditionProfile smallNProfile = ConditionProfile.createBinaryProfile();
     private final Pbinom pbinom = new Pbinom();
@@ -108,7 +110,7 @@ public final class Qbinom implements StatsFunctions.Function3_2 {
 
         /* y := approx.value (Cornish-Fisher expansion) : */
 
-        double z = Random2.qnorm5(p, 0., 1., /* lowerTail */true, /* logP */false);
+        double z = Qnorm.qnorm(p, 0., 1., /* lowerTail */true, /* logP */false);
         double y = Math.floor(mu + sigma * (z + gamma * (z * z - 1) / 6) + 0.5);
 
         if (y > n) {
diff --git a/com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/stats/Qf.java b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/nmath/distr/Qf.java
similarity index 79%
rename from com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/stats/Qf.java
rename to com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/nmath/distr/Qf.java
index 94d0967d1c..f67d965381 100644
--- a/com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/stats/Qf.java
+++ b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/nmath/distr/Qf.java
@@ -6,15 +6,18 @@
  * Copyright (C) 1998 Ross Ihaka
  * Copyright (c) 2000--2015, The R Core Team
  * Copyright (c) 2005, The R Foundation
- * Copyright (c) 2016, Oracle and/or its affiliates
+ * Copyright (c) 2016, 2017, Oracle and/or its affiliates
  *
  * All rights reserved.
  */
-package com.oracle.truffle.r.library.stats;
-
-import com.oracle.truffle.r.library.stats.Chisq.QChisq;
-import com.oracle.truffle.r.library.stats.DPQ.EarlyReturn;
-import com.oracle.truffle.r.library.stats.StatsFunctions.Function3_2;
+package com.oracle.truffle.r.runtime.nmath.distr;
+
+import com.oracle.truffle.r.runtime.nmath.DPQ;
+import com.oracle.truffle.r.runtime.nmath.DPQ.EarlyReturn;
+import com.oracle.truffle.r.runtime.nmath.MathFunctions.Function3_2;
+import com.oracle.truffle.r.runtime.nmath.RMath;
+import com.oracle.truffle.r.runtime.nmath.RMathError;
+import com.oracle.truffle.r.runtime.nmath.distr.Chisq.QChisq;
 
 public final class Qf implements Function3_2 {
     private final QBeta qbeta = new QBeta();
diff --git a/com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/stats/Qnf.java b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/nmath/distr/Qnf.java
similarity index 79%
rename from com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/stats/Qnf.java
rename to com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/nmath/distr/Qnf.java
index 54a6acf636..c443aba193 100644
--- a/com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/stats/Qnf.java
+++ b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/nmath/distr/Qnf.java
@@ -4,14 +4,16 @@
  * http://www.gnu.org/licenses/gpl-2.0.html
  *
  * Copyright (c) 2006-8, The R Core Team
- * Copyright (c) 2016, Oracle and/or its affiliates
+ * Copyright (c) 2016, 2017, Oracle and/or its affiliates
  *
  * All rights reserved.
  */
-package com.oracle.truffle.r.library.stats;
+package com.oracle.truffle.r.runtime.nmath.distr;
 
-import com.oracle.truffle.r.library.stats.DPQ.EarlyReturn;
-import com.oracle.truffle.r.library.stats.StatsFunctions.Function4_2;
+import com.oracle.truffle.r.runtime.nmath.DPQ;
+import com.oracle.truffle.r.runtime.nmath.DPQ.EarlyReturn;
+import com.oracle.truffle.r.runtime.nmath.MathFunctions.Function4_2;
+import com.oracle.truffle.r.runtime.nmath.RMathError;
 
 public final class Qnf implements Function4_2 {
     private final QNChisq qnchisq = new QNChisq();
diff --git a/com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/stats/Qnorm.java b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/nmath/distr/Qnorm.java
similarity index 85%
rename from com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/stats/Qnorm.java
rename to com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/nmath/distr/Qnorm.java
index 42efb45623..e7964e170d 100644
--- a/com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/stats/Qnorm.java
+++ b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/nmath/distr/Qnorm.java
@@ -6,7 +6,7 @@
  * Copyright (C) 1998 Ross Ihaka
  * Copyright (c) 2000--2014, The R Core Team
  * Copyright (c) 2007, The R Foundation
- * Copyright (c) 2016, 2016, Oracle and/or its affiliates
+ * Copyright (c) 2016, 2017, Oracle and/or its affiliates
  *
  * All rights reserved.
  */
@@ -14,14 +14,16 @@
  *  based on AS 111 (C) 1977 Royal Statistical Society
  *  and   on AS 241 (C) 1988 Royal Statistical Society
  */
-package com.oracle.truffle.r.library.stats;
+package com.oracle.truffle.r.runtime.nmath.distr;
 
 import com.oracle.truffle.api.profiles.BranchProfile;
-import com.oracle.truffle.r.library.stats.DPQ.EarlyReturn;
+import com.oracle.truffle.r.runtime.nmath.DPQ;
+import com.oracle.truffle.r.runtime.nmath.DPQ.EarlyReturn;
+import com.oracle.truffle.r.runtime.nmath.MathFunctions.Function3_2;
 
 // transcribed from qnorm.c
 
-public final class Qnorm implements StatsFunctions.Function3_2 {
+public final class Qnorm implements Function3_2 {
     private final BranchProfile nanProfile = BranchProfile.create();
 
     @Override
@@ -30,6 +32,7 @@ public final class Qnorm implements StatsFunctions.Function3_2 {
             nanProfile.enter();
             return p + mu + sigma;
         }
+
         try {
             DPQ.rqp01boundaries(p, Double.NEGATIVE_INFINITY, Double.POSITIVE_INFINITY, lowerTail, logP);
         } catch (EarlyReturn early) {
@@ -44,6 +47,24 @@ public final class Qnorm implements StatsFunctions.Function3_2 {
             return mu;
         }
 
+        return qnormImpl(p, mu, sigma, lowerTail, logP);
+    }
+
+    /**
+     * Static version without arguments validation.
+     */
+    public static double qnorm(double p, double mu, double sigma, boolean lowerTail, boolean logP) {
+        try {
+            DPQ.rqp01boundaries(p, Double.NEGATIVE_INFINITY, Double.POSITIVE_INFINITY, lowerTail, logP);
+        } catch (EarlyReturn early) {
+            return early.result;
+        }
+
+        return qnormImpl(p, mu, sigma, lowerTail, logP);
+    }
+
+    private static double qnormImpl(double p, double mu, double sigma, boolean lowerTail, boolean logP) {
+
         double p2 = DPQ.rdtqiv(p, lowerTail, logP); /* real lower_tail prob. p */
         double q = p2 - 0.5;
 
@@ -53,10 +74,10 @@ public final class Qnorm implements StatsFunctions.Function3_2 {
         /* double ppnd16_(double *p, long *ifault) */
         /*
          * ALGORITHM AS241 APPL. STATIST. (1988) VOL. 37, NO. 3
-         * 
+         *
          * Produces the normal deviate Z corresponding to a given lower tail area of P; Z is
          * accurate to about 1 part in 10**16.
-         * 
+         *
          * (original fortran code used PARAMETER(..) for the coefficients and provided hash codes
          * for checking them...)
          */
diff --git a/com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/stats/Qt.java b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/nmath/distr/Qt.java
similarity index 89%
rename from com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/stats/Qt.java
rename to com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/nmath/distr/Qt.java
index 5c52750435..898255050e 100644
--- a/com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/stats/Qt.java
+++ b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/nmath/distr/Qt.java
@@ -6,23 +6,26 @@
  * Copyright (C) 1998 Ross Ihaka
  * Copyright (c) 2000-2013, The R Core Team
  * Copyright (c) 2003-2013, The R Foundation
- * Copyright (c) 2016, Oracle and/or its affiliates
+ * Copyright (c) 2016, 2017, Oracle and/or its affiliates
  *
  * All rights reserved.
  */
-package com.oracle.truffle.r.library.stats;
-
-import static com.oracle.truffle.r.library.stats.MathConstants.DBL_EPSILON;
-import static com.oracle.truffle.r.library.stats.MathConstants.DBL_MANT_DIG;
-import static com.oracle.truffle.r.library.stats.MathConstants.DBL_MIN;
-import static com.oracle.truffle.r.library.stats.MathConstants.M_1_PI;
-import static com.oracle.truffle.r.library.stats.MathConstants.M_LN2;
-import static com.oracle.truffle.r.library.stats.MathConstants.M_PI;
-import static com.oracle.truffle.r.library.stats.MathConstants.M_PI_2;
-import static com.oracle.truffle.r.library.stats.MathConstants.M_SQRT2;
-
-import com.oracle.truffle.r.library.stats.DPQ.EarlyReturn;
-import com.oracle.truffle.r.library.stats.StatsFunctions.Function2_2;
+package com.oracle.truffle.r.runtime.nmath.distr;
+
+import static com.oracle.truffle.r.runtime.nmath.MathConstants.DBL_EPSILON;
+import static com.oracle.truffle.r.runtime.nmath.MathConstants.DBL_MANT_DIG;
+import static com.oracle.truffle.r.runtime.nmath.MathConstants.DBL_MIN;
+import static com.oracle.truffle.r.runtime.nmath.MathConstants.M_1_PI;
+import static com.oracle.truffle.r.runtime.nmath.MathConstants.M_LN2;
+import static com.oracle.truffle.r.runtime.nmath.MathConstants.M_PI;
+import static com.oracle.truffle.r.runtime.nmath.MathConstants.M_PI_2;
+import static com.oracle.truffle.r.runtime.nmath.MathConstants.M_SQRT2;
+
+import com.oracle.truffle.r.runtime.nmath.DPQ;
+import com.oracle.truffle.r.runtime.nmath.DPQ.EarlyReturn;
+import com.oracle.truffle.r.runtime.nmath.MathFunctions.Function2_2;
+import com.oracle.truffle.r.runtime.nmath.RMath;
+import com.oracle.truffle.r.runtime.nmath.RMathError;
 
 public final class Qt implements Function2_2 {
     private static final double eps = 1.e-12;
diff --git a/com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/stats/QuantileSearch.java b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/nmath/distr/QuantileSearch.java
similarity index 97%
rename from com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/stats/QuantileSearch.java
rename to com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/nmath/distr/QuantileSearch.java
index 05ea19680f..b9e0e2b736 100644
--- a/com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/stats/QuantileSearch.java
+++ b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/nmath/distr/QuantileSearch.java
@@ -10,7 +10,9 @@
  *
  * All rights reserved.
  */
-package com.oracle.truffle.r.library.stats;
+package com.oracle.truffle.r.runtime.nmath.distr;
+
+import com.oracle.truffle.r.runtime.nmath.RMath;
 
 /**
  * Searches for a quantile of given random variable using it's distribution function. The search
diff --git a/com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/stats/RBeta.java b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/nmath/distr/RBeta.java
similarity index 89%
rename from com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/stats/RBeta.java
rename to com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/nmath/distr/RBeta.java
index 0aceb6a799..550441cae9 100644
--- a/com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/stats/RBeta.java
+++ b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/nmath/distr/RBeta.java
@@ -10,15 +10,16 @@
  *
  * All rights reserved.
  */
-package com.oracle.truffle.r.library.stats;
+package com.oracle.truffle.r.runtime.nmath.distr;
 
-import static com.oracle.truffle.r.library.stats.MathConstants.DBL_MAX_EXP;
-import static com.oracle.truffle.r.library.stats.MathConstants.M_LN2;
-import static com.oracle.truffle.r.library.stats.RMath.fmax2;
-import static com.oracle.truffle.r.library.stats.RMath.fmin2;
+import static com.oracle.truffle.r.runtime.nmath.MathConstants.DBL_MAX_EXP;
+import static com.oracle.truffle.r.runtime.nmath.MathConstants.M_LN2;
+import static com.oracle.truffle.r.runtime.nmath.RMath.fmax2;
+import static com.oracle.truffle.r.runtime.nmath.RMath.fmin2;
 
-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.nmath.RMathError;
+import com.oracle.truffle.r.runtime.nmath.RandomFunctions.RandFunction2_Double;
+import com.oracle.truffle.r.runtime.nmath.RandomFunctions.RandomNumberProvider;
 
 public final class RBeta extends RandFunction2_Double {
 
diff --git a/com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/stats/RGamma.java b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/nmath/distr/RGamma.java
similarity index 93%
rename from com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/stats/RGamma.java
rename to com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/nmath/distr/RGamma.java
index f3546d5e1a..867c643265 100644
--- a/com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/stats/RGamma.java
+++ b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/nmath/distr/RGamma.java
@@ -5,16 +5,18 @@
  *
  * Copyright (C) 1998 Ross Ihaka
  * Copyright (c) 1998--2008, The R Core Team
- * Copyright (c) 2016, 2016, Oracle and/or its affiliates
+ * Copyright (c) 2016, 2017, Oracle and/or its affiliates
  *
  * All rights reserved.
  */
-package com.oracle.truffle.r.library.stats;
+package com.oracle.truffle.r.runtime.nmath.distr;
 
-import static com.oracle.truffle.r.library.stats.TOMS708.fabs;
+import static com.oracle.truffle.r.runtime.nmath.TOMS708.fabs;
 
-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.nmath.RMath;
+import com.oracle.truffle.r.runtime.nmath.RMathError;
+import com.oracle.truffle.r.runtime.nmath.RandomFunctions.RandFunction2_Double;
+import com.oracle.truffle.r.runtime.nmath.RandomFunctions.RandomNumberProvider;
 
 public final class RGamma extends RandFunction2_Double {
     private static final double sqrt32 = 5.656854;
diff --git a/com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/stats/RHyper.java b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/nmath/distr/RHyper.java
similarity index 96%
rename from com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/stats/RHyper.java
rename to com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/nmath/distr/RHyper.java
index fb549a90f9..2b501eb81d 100644
--- a/com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/stats/RHyper.java
+++ b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/nmath/distr/RHyper.java
@@ -6,20 +6,21 @@
  * 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
+ * Copyright (c) 2016, 2017, Oracle and/or its affiliates
  *
  * All rights reserved.
  */
-package com.oracle.truffle.r.library.stats;
+package com.oracle.truffle.r.runtime.nmath.distr;
 
-import static com.oracle.truffle.r.library.stats.MathConstants.M_LN_SQRT_2PI;
-import static com.oracle.truffle.r.library.stats.RMath.forceint;
+import static com.oracle.truffle.r.runtime.nmath.MathConstants.M_LN_SQRT_2PI;
+import static com.oracle.truffle.r.runtime.nmath.RMath.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;
+import com.oracle.truffle.r.runtime.nmath.RMathError;
+import com.oracle.truffle.r.runtime.nmath.RandomFunctions.RandFunction3_Double;
+import com.oracle.truffle.r.runtime.nmath.RandomFunctions.RandomNumberProvider;
 
 public final class RHyper extends RandFunction3_Double {
     private static final double[] al = {
diff --git a/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/nmath/distr/RMultinom.java b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/nmath/distr/RMultinom.java
new file mode 100644
index 0000000000..62336feae6
--- /dev/null
+++ b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/nmath/distr/RMultinom.java
@@ -0,0 +1,100 @@
+/*
+ * 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, 2017, Oracle and/or its affiliates
+ *
+ * All rights reserved.
+ */
+package com.oracle.truffle.r.runtime.nmath.distr;
+
+import static com.oracle.truffle.r.runtime.RError.SHOW_CALLER;
+
+import com.oracle.truffle.api.CompilerDirectives.TruffleBoundary;
+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.nmath.RandomFunctions.RandomNumberProvider;
+
+public final class RMultinom {
+    private RMultinom() {
+        // only static method rmultinom
+    }
+
+    /**
+     * 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
+    public static boolean rmultinom(int nIn, double[] prob, int maxK, int[] rN, int rnStartIdx, RandomNumberProvider rand, Rbinom rbinom) {
+        /*
+         * 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.
+         */
+
+        int n = nIn;
+        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 !
+         */
+        /* LDOUBLE */double pTot = 0.;
+        for (int k = 0; k < maxK; k++) {
+            double pp = prob[k];
+            if (!Double.isFinite(pp) || pp < 0. || pp > 1.) {
+                rN[rnStartIdx + k] = RRuntime.INT_NA;
+                return false;
+            }
+            pTot += pp;
+            rN[rnStartIdx + k] = 0;
+        }
+
+        /* LDOUBLE */double probSum = Math.abs(pTot - 1);
+        if (probSum > 1e-7) {
+            throw RError.error(SHOW_CALLER, Message.GENERIC, String.format("rbinom: probability sum should be 1, but is %g", pTot));
+        }
+        if (n == 0) {
+            return true;
+        }
+        if (maxK == 1 && pTot == 0.) {
+            return true; /* trivial border case: do as rbinom */
+        }
+
+        /* Generate the first K-1 obs. via binomials */
+        for (int k = 0; k < maxK - 1; k++) {
+            /* (p_tot, n) are for "remaining binomial" */
+            /* LDOUBLE */double probK = prob[k];
+            if (probK != 0.) {
+                double pp = probK / pTot;
+                // System.out.printf("[%d] %.17f\n", k + 1, pp);
+                rN[rnStartIdx + k] = ((pp < 1.) ? (int) rbinom.execute(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 -= probK;
+        }
+
+        rN[rnStartIdx + maxK - 1] = n;
+        return true;
+    }
+}
diff --git a/com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/stats/RNBinom.java b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/nmath/distr/RNBinom.java
similarity index 82%
rename from com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/stats/RNBinom.java
rename to com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/nmath/distr/RNBinom.java
index e8f56f4509..94ace3544b 100644
--- a/com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/stats/RNBinom.java
+++ b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/nmath/distr/RNBinom.java
@@ -5,16 +5,17 @@
  *
  * Copyright (C) 1998 Ross Ihaka
  * Copyright (c) 2000--2016, The R Core Team
- * Copyright (c) 2016, Oracle and/or its affiliates
+ * Copyright (c) 2016, 2017, Oracle and/or its affiliates
  *
  * All rights reserved.
  */
-package com.oracle.truffle.r.library.stats;
+package com.oracle.truffle.r.runtime.nmath.distr;
 
-import static com.oracle.truffle.r.library.stats.MathConstants.DBL_MAX;
+import static com.oracle.truffle.r.runtime.nmath.MathConstants.DBL_MAX;
 
-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.nmath.RMathError;
+import com.oracle.truffle.r.runtime.nmath.RandomFunctions.RandFunction2_Double;
+import com.oracle.truffle.r.runtime.nmath.RandomFunctions.RandomNumberProvider;
 
 public final class RNBinom {
     private RNBinom() {
diff --git a/com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/stats/RNchisq.java b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/nmath/distr/RNchisq.java
similarity index 76%
rename from com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/stats/RNchisq.java
rename to com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/nmath/distr/RNchisq.java
index f0d523cf14..ca4115c927 100644
--- a/com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/stats/RNchisq.java
+++ b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/nmath/distr/RNchisq.java
@@ -5,16 +5,17 @@
  *
  * Copyright (c) 1995-2015, The R Core Team
  * Copyright (c) 2015, The R Foundation
- * Copyright (c) 2016, Oracle and/or its affiliates
+ * Copyright (c) 2016, 2017, Oracle and/or its affiliates
  *
  * All rights reserved.
  */
 
 // TODO: fix copyright
-package com.oracle.truffle.r.library.stats;
+package com.oracle.truffle.r.runtime.nmath.distr;
 
-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.nmath.RMathError;
+import com.oracle.truffle.r.runtime.nmath.RandomFunctions.RandFunction2_Double;
+import com.oracle.truffle.r.runtime.nmath.RandomFunctions.RandomNumberProvider;
 
 public final class RNchisq extends RandFunction2_Double {
     private final RGamma rgamma = new RGamma();
diff --git a/com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/stats/RPois.java b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/nmath/distr/RPois.java
similarity index 95%
rename from com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/stats/RPois.java
rename to com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/nmath/distr/RPois.java
index 36759275c3..587a56fb40 100644
--- a/com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/stats/RPois.java
+++ b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/nmath/distr/RPois.java
@@ -5,16 +5,19 @@
  *
  * Copyright (C) 1998 Ross Ihaka
  * Copyright (c) 1998--2008, The R Core Team
- * Copyright (c) 2016, 2016, Oracle and/or its affiliates
+ * Copyright (c) 2016, 2017, Oracle and/or its affiliates
  *
  * All rights reserved.
  */
-package com.oracle.truffle.r.library.stats;
+package com.oracle.truffle.r.runtime.nmath.distr;
 
-import static com.oracle.truffle.r.library.stats.MathConstants.M_1_SQRT_2PI;
+import static com.oracle.truffle.r.runtime.nmath.MathConstants.M_1_SQRT_2PI;
 
-import com.oracle.truffle.r.library.stats.RandGenerationFunctions.RandFunction1_Double;
-import com.oracle.truffle.r.library.stats.RandGenerationFunctions.RandomNumberProvider;
+import com.oracle.truffle.r.runtime.nmath.RMath;
+import com.oracle.truffle.r.runtime.nmath.RMathError;
+import com.oracle.truffle.r.runtime.nmath.RandomFunctions.RandFunction1_Double;
+import com.oracle.truffle.r.runtime.nmath.RandomFunctions.RandomNumberProvider;
+import com.oracle.truffle.r.runtime.nmath.TOMS708;
 
 public final class RPois extends RandFunction1_Double {
 
diff --git a/com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/stats/Rbinom.java b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/nmath/distr/Rbinom.java
similarity index 96%
rename from com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/stats/Rbinom.java
rename to com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/nmath/distr/Rbinom.java
index 4f9080aae6..020784e2b7 100644
--- a/com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/stats/Rbinom.java
+++ b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/nmath/distr/Rbinom.java
@@ -6,15 +6,17 @@
  * 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
+ * Copyright (c) 2016, 2017, Oracle and/or its affiliates
  *
  * All rights reserved.
  */
-package com.oracle.truffle.r.library.stats;
+package com.oracle.truffle.r.runtime.nmath.distr;
 
-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.nmath.Arithmetic;
+import com.oracle.truffle.r.runtime.nmath.RMath;
+import com.oracle.truffle.r.runtime.nmath.RandomFunctions.RandFunction2_Double;
+import com.oracle.truffle.r.runtime.nmath.RandomFunctions.RandomNumberProvider;
 
 // transcribed from rbinom.c
 
diff --git a/com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/stats/Rf.java b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/nmath/distr/Rf.java
similarity index 71%
rename from com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/stats/Rf.java
rename to com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/nmath/distr/Rf.java
index 0c1643b024..56dfc48308 100644
--- a/com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/stats/Rf.java
+++ b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/nmath/distr/Rf.java
@@ -5,14 +5,15 @@
  *
  * Copyright (C) 1998 Ross Ihaka
  * Copyright (c) 1998--2008, The R Core Team
- * Copyright (c) 2016, 2016, Oracle and/or its affiliates
+ * Copyright (c) 2016, 2017, Oracle and/or its affiliates
  *
  * All rights reserved.
  */
-package com.oracle.truffle.r.library.stats;
+package com.oracle.truffle.r.runtime.nmath.distr;
 
-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.nmath.RMathError;
+import com.oracle.truffle.r.runtime.nmath.RandomFunctions.RandFunction2_Double;
+import com.oracle.truffle.r.runtime.nmath.RandomFunctions.RandomNumberProvider;
 
 public final class Rf extends RandFunction2_Double {
     @Override
diff --git a/com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/stats/Rnorm.java b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/nmath/distr/Rnorm.java
similarity index 81%
rename from com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/stats/Rnorm.java
rename to com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/nmath/distr/Rnorm.java
index 5cdb828e58..8d30f497c2 100644
--- a/com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/stats/Rnorm.java
+++ b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/nmath/distr/Rnorm.java
@@ -5,17 +5,18 @@
  *
  * Copyright (c) 1995-2012, The R Core Team
  * Copyright (c) 2003, The R Foundation
- * Copyright (c) 2013, 2016, Oracle and/or its affiliates
+ * Copyright (c) 2013, 2017, Oracle and/or its affiliates
  *
  * All rights reserved.
  */
-package com.oracle.truffle.r.library.stats;
+package com.oracle.truffle.r.runtime.nmath.distr;
 
 import com.oracle.truffle.api.profiles.BranchProfile;
 import com.oracle.truffle.api.profiles.ConditionProfile;
 import com.oracle.truffle.api.profiles.ValueProfile;
-import com.oracle.truffle.r.library.stats.RandGenerationFunctions.RandFunction2_Double;
-import com.oracle.truffle.r.library.stats.RandGenerationFunctions.RandomNumberProvider;
+import com.oracle.truffle.r.runtime.nmath.RMathError;
+import com.oracle.truffle.r.runtime.nmath.RandomFunctions.RandFunction2_Double;
+import com.oracle.truffle.r.runtime.nmath.RandomFunctions.RandomNumberProvider;
 
 public final class Rnorm extends RandFunction2_Double {
     private final BranchProfile errorProfile = BranchProfile.create();
diff --git a/com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/stats/Rt.java b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/nmath/distr/Rt.java
similarity index 57%
rename from com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/stats/Rt.java
rename to com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/nmath/distr/Rt.java
index 3804a50961..dffa27a4e7 100644
--- a/com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/stats/Rt.java
+++ b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/nmath/distr/Rt.java
@@ -5,16 +5,16 @@
  *
  * Copyright (C) 1998 Ross Ihaka
  * Copyright (c) 1998--2008, The R Core Team
- * Copyright (c) 2016, 2016, Oracle and/or its affiliates
+ * Copyright (c) 2016, 2017, Oracle and/or its affiliates
  *
  * All rights reserved.
  */
-package com.oracle.truffle.r.library.stats;
+package com.oracle.truffle.r.runtime.nmath.distr;
 
-import static com.oracle.truffle.r.library.stats.Chisq.RChisq.rchisq;
-
-import com.oracle.truffle.r.library.stats.RandGenerationFunctions.RandFunction1_Double;
-import com.oracle.truffle.r.library.stats.RandGenerationFunctions.RandomNumberProvider;
+import com.oracle.truffle.r.runtime.nmath.RMathError;
+import com.oracle.truffle.r.runtime.nmath.RandomFunctions.RandFunction1_Double;
+import com.oracle.truffle.r.runtime.nmath.RandomFunctions.RandomNumberProvider;
+import com.oracle.truffle.r.runtime.nmath.distr.Chisq.RChisq;
 
 public final class Rt extends RandFunction1_Double {
     @Override
@@ -26,7 +26,7 @@ public final class Rt extends RandFunction1_Double {
         if (!Double.isFinite(df)) {
             return rand.normRand();
         } else {
-            return rand.normRand() / Math.sqrt(rchisq(df, rand) / df);
+            return rand.normRand() / Math.sqrt(RChisq.rchisq(df, rand) / df);
         }
     }
 }
diff --git a/com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/stats/SExp.java b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/nmath/distr/SExp.java
similarity index 89%
rename from com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/stats/SExp.java
rename to com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/nmath/distr/SExp.java
index 924bbf783c..d2ecba05f8 100644
--- a/com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/stats/SExp.java
+++ b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/nmath/distr/SExp.java
@@ -5,18 +5,19 @@
  *
  * Copyright (C) 1998 Ross Ihaka
  * Copyright (c) 1998--2008, The R Core Team
- * Copyright (c) 2016, 2016, Oracle and/or its affiliates
+ * Copyright (c) 2016, 2017, Oracle and/or its affiliates
  *
  * All rights reserved.
  */
-package com.oracle.truffle.r.library.stats;
+package com.oracle.truffle.r.runtime.nmath.distr;
 
 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.
+ * in GnuR. Some other distributions can be generated by transformations standard exponential
+ * disiontri. This is meant as common functinality for those.
  */
 public final class SExp {
     private SExp() {
diff --git a/com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/stats/SNorm.java b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/nmath/distr/SNorm.java
similarity index 78%
rename from com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/stats/SNorm.java
rename to com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/nmath/distr/SNorm.java
index 0f6737a375..d818315b6d 100644
--- a/com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/stats/SNorm.java
+++ b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/nmath/distr/SNorm.java
@@ -5,11 +5,11 @@
  *
  * Copyright (C) 1998 Ross Ihaka
  * Copyright (c) 1998--2008, The R Core Team
- * Copyright (c) 2016, 2016, Oracle and/or its affiliates
+ * Copyright (c) 2016, 2017, Oracle and/or its affiliates
  *
  * All rights reserved.
  */
-package com.oracle.truffle.r.library.stats;
+package com.oracle.truffle.r.runtime.nmath.distr;
 
 import com.oracle.truffle.r.runtime.RError;
 import com.oracle.truffle.r.runtime.rng.RRNG.NormKind;
@@ -17,7 +17,8 @@ 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.
+ * {@code snorm.c} in GnuR. Some other distributions can be generated by transformations of N(0,1).
+ * This is meant as common functinality for those.
  */
 public final class SNorm {
     private SNorm() {
@@ -35,6 +36,6 @@ public final class SNorm {
         /* 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);
+        return Qnorm.qnorm(u1 / BIG, 0.0, 1.0, true, false);
     }
 }
diff --git a/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/nmath/distr/Signrank.java b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/nmath/distr/Signrank.java
new file mode 100644
index 0000000000..a45f69b73f
--- /dev/null
+++ b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/nmath/distr/Signrank.java
@@ -0,0 +1,87 @@
+/*
+ * 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, 2017, Oracle and/or its affiliates
+ *
+ * All rights reserved.
+ */
+
+package com.oracle.truffle.r.runtime.nmath.distr;
+
+import static com.oracle.truffle.r.runtime.RError.Message.GENERIC;
+import static com.oracle.truffle.r.runtime.nmath.RMath.forceint;
+
+import com.oracle.truffle.api.CompilerDirectives.TruffleBoundary;
+import com.oracle.truffle.r.runtime.RError;
+import com.oracle.truffle.r.runtime.nmath.RMathError;
+import com.oracle.truffle.r.runtime.nmath.RandomFunctions.RandFunction1_Double;
+import com.oracle.truffle.r.runtime.nmath.RandomFunctions.RandomNumberProvider;
+
+public final class Signrank {
+    private Signrank() {
+        // only static members
+    }
+
+    /**
+     * Holds cache for the dynamic algorithm that wilcox uses.
+     */
+    public static final class SignrankData {
+        private static final ThreadLocal<double[]> data = new ThreadLocal<>();
+
+        @TruffleBoundary
+        static double[] getData(int n) {
+            double[] result = data.get();
+            int u = n * (n + 1) / 2;
+            int c = (u / 2);
+
+            if (result != null && (result.length <= c)) {
+                result = null;
+            }
+            if (result == null) {
+                try {
+                    result = new double[c + 1];
+                } catch (OutOfMemoryError e) {
+                    throw RError.error(RError.SHOW_CALLER, GENERIC, "signrank allocation error");
+                }
+                data.set(result);
+            }
+            return result;
+        }
+
+        public static void freeData() {
+            data.set(null);
+        }
+    }
+
+    public static final class RSignrank extends RandFunction1_Double {
+        @Override
+        public double execute(double nIn, RandomNumberProvider rand) {
+            if (Double.isNaN(nIn)) {
+                return nIn;
+            }
+            if (Double.isInfinite(nIn)) {
+                // In GnuR these "results" seem to be generated due to the behaviour of R_forceint,
+                // and the "(int) n" cast, which ends up casting +/-infinity to integer...
+                return nIn < 0 ? RMathError.defaultError() : 0;
+            }
+
+            double n = forceint(nIn);
+            if (n < 0) {
+                return RMathError.defaultError();
+            }
+
+            if (n == 0) {
+                return 0;
+            }
+            double r = 0.0;
+            int k = (int) n;
+            for (int i = 0; i < k; i++) {
+                r += (i + 1) * Math.floor(rand.unifRand() + 0.5);
+            }
+            return r;
+        }
+    }
+}
diff --git a/com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/stats/Unif.java b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/nmath/distr/Unif.java
similarity index 86%
rename from com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/stats/Unif.java
rename to com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/nmath/distr/Unif.java
index b708907b8e..e06b69ba14 100644
--- a/com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/stats/Unif.java
+++ b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/nmath/distr/Unif.java
@@ -5,21 +5,23 @@
  *
  * Copyright (C) 1998 Ross Ihaka
  * Copyright (c) 2000-2006, The R Core Team
- * Copyright (c) 2013, 2016, Oracle and/or its affiliates
+ * Copyright (c) 2013, 2017, Oracle and/or its affiliates
  *
  * All rights reserved.
  */
-package com.oracle.truffle.r.library.stats;
+package com.oracle.truffle.r.runtime.nmath.distr;
 
 import com.oracle.truffle.api.profiles.BranchProfile;
 import com.oracle.truffle.api.profiles.ConditionProfile;
 import com.oracle.truffle.api.profiles.ValueProfile;
-import com.oracle.truffle.r.library.stats.DPQ.EarlyReturn;
-import com.oracle.truffle.r.library.stats.RandGenerationFunctions.RandFunction2_Double;
-import com.oracle.truffle.r.library.stats.RandGenerationFunctions.RandomNumberProvider;
-import com.oracle.truffle.r.library.stats.StatsFunctions.Function3_1;
-import com.oracle.truffle.r.library.stats.StatsFunctions.Function3_2;
 import com.oracle.truffle.r.runtime.RRuntime;
+import com.oracle.truffle.r.runtime.nmath.DPQ;
+import com.oracle.truffle.r.runtime.nmath.DPQ.EarlyReturn;
+import com.oracle.truffle.r.runtime.nmath.MathFunctions.Function3_1;
+import com.oracle.truffle.r.runtime.nmath.MathFunctions.Function3_2;
+import com.oracle.truffle.r.runtime.nmath.RMathError;
+import com.oracle.truffle.r.runtime.nmath.RandomFunctions.RandFunction2_Double;
+import com.oracle.truffle.r.runtime.nmath.RandomFunctions.RandomNumberProvider;
 
 public final class Unif {
     private Unif() {
diff --git a/com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/stats/Weibull.java b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/nmath/distr/Weibull.java
similarity index 85%
rename from com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/stats/Weibull.java
rename to com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/nmath/distr/Weibull.java
index 2f40d28f57..b2febc8ffe 100644
--- a/com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/stats/Weibull.java
+++ b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/nmath/distr/Weibull.java
@@ -9,13 +9,16 @@
  *
  * All rights reserved.
  */
-package com.oracle.truffle.r.library.stats;
+package com.oracle.truffle.r.runtime.nmath.distr;
 
-import com.oracle.truffle.r.library.stats.DPQ.EarlyReturn;
-import com.oracle.truffle.r.library.stats.RandGenerationFunctions.RandFunction2_Double;
-import com.oracle.truffle.r.library.stats.RandGenerationFunctions.RandomNumberProvider;
-import com.oracle.truffle.r.library.stats.StatsFunctions.Function3_1;
-import com.oracle.truffle.r.library.stats.StatsFunctions.Function3_2;
+import com.oracle.truffle.r.runtime.nmath.DPQ;
+import com.oracle.truffle.r.runtime.nmath.DPQ.EarlyReturn;
+import com.oracle.truffle.r.runtime.nmath.MathFunctions.Function3_1;
+import com.oracle.truffle.r.runtime.nmath.MathFunctions.Function3_2;
+import com.oracle.truffle.r.runtime.nmath.RMath;
+import com.oracle.truffle.r.runtime.nmath.RMathError;
+import com.oracle.truffle.r.runtime.nmath.RandomFunctions.RandFunction2_Double;
+import com.oracle.truffle.r.runtime.nmath.RandomFunctions.RandomNumberProvider;
 
 public final class Weibull {
     private Weibull() {
diff --git a/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/nmath/distr/Wilcox.java b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/nmath/distr/Wilcox.java
new file mode 100644
index 0000000000..feee67ad95
--- /dev/null
+++ b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/nmath/distr/Wilcox.java
@@ -0,0 +1,360 @@
+/*
+ * 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, 2017, Oracle and/or its affiliates
+ *
+ * All rights reserved.
+ */
+
+package com.oracle.truffle.r.runtime.nmath.distr;
+
+import static com.oracle.truffle.r.runtime.RError.Message.CALLOC_COULD_NOT_ALLOCATE_INF;
+import static com.oracle.truffle.r.runtime.nmath.Choose.choose;
+import static com.oracle.truffle.r.runtime.nmath.Choose.lchoose;
+import static com.oracle.truffle.r.runtime.nmath.MathConstants.DBL_EPSILON;
+
+import java.util.Arrays;
+
+import com.oracle.truffle.api.CompilerDirectives.TruffleBoundary;
+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.nmath.DPQ;
+import com.oracle.truffle.r.runtime.nmath.DPQ.EarlyReturn;
+import com.oracle.truffle.r.runtime.nmath.MathFunctions.Function3_1;
+import com.oracle.truffle.r.runtime.nmath.MathFunctions.Function3_2;
+import com.oracle.truffle.r.runtime.nmath.RMath;
+import com.oracle.truffle.r.runtime.nmath.RMathError;
+import com.oracle.truffle.r.runtime.nmath.RandomFunctions.RandFunction2_Double;
+import com.oracle.truffle.r.runtime.nmath.RandomFunctions.RandomNumberProvider;
+import com.oracle.truffle.r.runtime.nmath.TOMS708;
+
+public final class Wilcox {
+    /**
+     * Wilcox will always allocate at least this size of data (for the dynamic programming
+     * algorithm) in order to avoid re-allocations.
+     */
+    private static final int WILCOX_MIN_ALLOCATE = 50;
+
+    /**
+     * Anything above this we do not even try to allocate. This means that some of the values can be
+     * safely stored in integers (will not be greater than Integer.MAX_VALUE). Note: somewhere
+     * around this value, GnuR running dwilcox gets killed on Linux with 8GB RAM.
+     */
+    private static final int WILCOX_MAX_ALLOCATE = 10000;
+
+    private Wilcox() {
+        // only static members
+    }
+
+    /**
+     * Holds cache for the dynamic algorithm that wilcox uses.
+     */
+    public static final class WilcoxData {
+        private static final ThreadLocal<double[][][]> data = new ThreadLocal<>();
+
+        static boolean checkSize(double m, double n) {
+            if (m > WILCOX_MAX_ALLOCATE || n > WILCOX_MAX_ALLOCATE) {
+                RMathError.warning(Message.WILCOX_TOO_MUCH_MEMORY, m, n);
+                return false;
+            }
+            return true;
+        }
+
+        @TruffleBoundary
+        static double[][][] getData(int mIn, int nIn) {
+            double[][][] result = data.get();
+            int m = mIn;
+            int n = nIn;
+            if (m > n) {
+                int tmp = n;
+                n = m;
+                m = tmp;
+            }
+
+            if (result != null && (result.length <= m || (result.length > 0 && result[0].length <= n))) {
+                // if the array is to small allocate it again
+                result = null;
+            }
+
+            if (result == null) {
+                m = Math.max(m, WILCOX_MIN_ALLOCATE);
+                n = Math.max(n, WILCOX_MIN_ALLOCATE);
+                try {
+                    result = new double[m + 1][n + 1][];
+                } catch (OutOfMemoryError e) {
+                    // GnuR seems to be reporting the same number regardless of the actual size
+                    throw RError.error(RError.SHOW_CALLER, CALLOC_COULD_NOT_ALLOCATE_INF);
+                }
+                data.set(result);
+            }
+            return result;
+        }
+
+        public static void freeData() {
+            data.set(null);
+        }
+    }
+
+    private static double cwilcox(double[][][] w, int kIn, int m, int n) {
+        int u = m * n;
+        if (kIn < 0 || kIn > u) {
+            return 0;
+        }
+        int c = u / 2;
+        int k = kIn <= c ? kIn : u - kIn; /* hence k <= floor(u / 2) */
+        assert k <= Math.floor(u);
+        int i;
+        int j;
+        if (m < n) {
+            i = m;
+            j = n;
+        } else {
+            i = n;
+            j = m;
+        } /* hence i <= j */
+        assert i <= j;
+
+        if (j == 0) {
+            /* and hence i == 0 */
+            assert i == 0;
+            return k == 0 ? 1 : 0;
+        }
+
+        /*
+         * We can simplify things if k is small. Consider the Mann-Whitney definition, and sort y.
+         * Then if the statistic is k, no more than k of the y's can be <= any x[i], and since they
+         * are sorted these can only be in the first k. So the count is the same as if there were
+         * just k y's.
+         */
+        if (j > 0 && k < j) {
+            return cwilcox(w, k, i, k);
+        }
+
+        if (w[i][j] == null) {
+            w[i][j] = new double[c + 1];
+            Arrays.fill(w[i][j], -1);
+        }
+        if (w[i][j][k] < 0) {
+            assert j != 0;
+            w[i][j][k] = cwilcox(w, k - j, i - 1, j) + cwilcox(w, k, i, j - 1);
+        }
+        return w[i][j][k];
+    }
+
+    public static final class QWilcox implements Function3_2 {
+        @Override
+        public double evaluate(double xIn, double mIn, double nIn, boolean lowerTail, boolean logP) {
+            if (Double.isNaN(xIn) || Double.isNaN(mIn) || Double.isNaN(nIn)) {
+                return (xIn + mIn + nIn);
+            }
+
+            if (!Double.isFinite(xIn) || !Double.isFinite(mIn) || !Double.isFinite(nIn)) {
+                return RMathError.defaultError();
+            }
+
+            try {
+                DPQ.rqp01check(xIn, logP);
+            } catch (EarlyReturn e) {
+                return e.result;
+            }
+
+            if (!WilcoxData.checkSize(mIn, nIn)) {
+                return Double.NaN;
+            }
+
+            double m = RMath.forceint(mIn);
+            double n = RMath.forceint(nIn);
+            if (m <= 0 || n <= 0) {
+                return RMathError.defaultError();
+            }
+
+            if (xIn == DPQ.rdt0(lowerTail, logP)) {
+                return 0;
+            }
+            if (xIn == DPQ.rdt1(lowerTail, logP)) {
+                return m * n;
+            }
+
+            double x = !logP && lowerTail ? xIn : DPQ.rdtqiv(xIn, lowerTail, logP);
+            int mm = (int) m;
+            int nn = (int) n;
+            double[][][] w = WilcoxData.getData(mm, nn);
+            double c = choose(m + n, n);
+            double p = 0;
+            int q = 0;
+            if (x <= 0.5) {
+                x = x - 10 * DBL_EPSILON;
+                while (true) {
+                    p += cwilcox(w, q, mm, nn) / c;
+                    if (p >= x) {
+                        break;
+                    }
+                    q++;
+                }
+            } else {
+                x = 1 - x + 10 * DBL_EPSILON;
+                while (true) {
+                    p += cwilcox(w, q, mm, nn) / c;
+                    if (p > x) {
+                        q = (int) (m * n - q);
+                        break;
+                    }
+                    q++;
+                }
+            }
+
+            return q;
+        }
+    }
+
+    public static final class PWilcox implements Function3_2 {
+
+        @Override
+        public double evaluate(double qIn, double mIn, double nIn, boolean lowerTail, boolean logP) {
+            if (Double.isNaN(qIn) || Double.isNaN(mIn) || Double.isNaN(nIn)) {
+                return (qIn + mIn + nIn);
+            }
+
+            if (!Double.isFinite(mIn) || !Double.isFinite(nIn)) {
+                return RMathError.defaultError();
+            }
+            double m = RMath.forceint(mIn);
+            double n = RMath.forceint(nIn);
+            if (m <= 0 || n <= 0) {
+                return RMathError.defaultError();
+            }
+
+            double q = Math.floor(qIn + 1e-7);
+            if (q < 0.0) {
+                return DPQ.rdt0(lowerTail, logP);
+            }
+            if (q >= m * n) {
+                return DPQ.rdt1(lowerTail, logP);
+            }
+
+            if (!WilcoxData.checkSize(mIn, nIn)) {
+                return Double.NaN;
+            }
+
+            // Note: since we limit m and n, and q < m*n, is should follow that m,n, and q < MAX_INT
+            int mm = (int) m;
+            int nn = (int) n;
+            double[][][] w = WilcoxData.getData(mm, nn);
+            double c = choose(m + n, n);
+            double p = 0;
+            /* Use summation of probs over the shorter range */
+            if (q <= (m * n / 2)) {
+                int qUpperInt = (int) Math.ceil(q);
+                for (int i = 0; i <= qUpperInt; i++) {
+                    p += cwilcox(w, i, mm, nn) / c;
+                }
+                return DPQ.rdtval(p, lowerTail, logP);
+            } else {
+                q = m * n - q;
+                int qUpperInt = (int) Math.ceil(q);
+                for (int i = 0; i < qUpperInt; i++) {
+                    p += cwilcox(w, i, mm, nn) / c;
+                }
+                /* swap lower tail: p = 1 - p; */
+                return DPQ.rdtval(p, !lowerTail, logP);
+            }
+        }
+    }
+
+    public static final class DWilcox implements Function3_1 {
+        @Override
+        public double evaluate(double x, double mIn, double nIn, boolean giveLog) {
+            /* NaNs propagated correctly */
+            if (Double.isNaN(x) || Double.isNaN(mIn) || Double.isNaN(nIn)) {
+                return (x + mIn + nIn);
+            }
+
+            if (!Double.isFinite(mIn) || !Double.isFinite(nIn)) {
+                if (mIn == Double.POSITIVE_INFINITY) {
+                    // To match GnuR's behaviour...
+                    return 0;
+                }
+                return RMathError.defaultError();
+            }
+
+            double m = RMath.forceint(mIn);
+            double n = RMath.forceint(nIn);
+            if (m <= 0 || n <= 0) {
+                return RMathError.defaultError();
+            }
+
+            if (TOMS708.fabs(x - RMath.forceint(x)) > 1e-7) {
+                return DPQ.rd0(giveLog);
+            }
+            double xInt = RMath.forceint(x);
+            if ((xInt < 0) || (xInt > m * n)) {
+                return DPQ.rd0(giveLog);
+            }
+
+            if (!WilcoxData.checkSize(mIn, nIn)) {
+                return Double.NaN;
+            }
+
+            // Note: since we limit m and n, and q < m*n, is should follow that m,n, and q < MAX_INT
+            int mm = (int) m;
+            int nn = (int) n;
+            int xx = (int) xInt;
+            double[][][] w = WilcoxData.getData(mm, nn);
+            return giveLog ? Math.log(cwilcox(w, xx, mm, nn)) - lchoose(m + n, n) : cwilcox(w, xx, mm, nn) / choose(m + n, n);
+        }
+    }
+
+    public static final class RWilcox extends RandFunction2_Double {
+        @Override
+        public double execute(double mIn, double nIn, RandomNumberProvider rand) {
+            /* NaNs propagated correctly */
+            if (Double.isNaN(mIn) || Double.isNaN(nIn)) {
+                return mIn + nIn;
+            }
+            if (!Double.isFinite(mIn) || !Double.isFinite(nIn)) {
+                // GnuR does not check this and tries to allocate the memory, we do check this, but
+                // fail with the same error message for compatibility reasons.
+                throw RError.error(RError.SHOW_CALLER, CALLOC_COULD_NOT_ALLOCATE_INF);
+            }
+
+            double m = RMath.round(mIn);
+            double n = RMath.round(nIn);
+            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);
+            }
+            return rwilcoxRaw(rand, n, (int) (m + n));
+        }
+
+        @TruffleBoundary
+        private double rwilcoxRaw(RandomNumberProvider rand, double n, int kIn) {
+            double r = 0.0;
+            int k = kIn;
+            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 (int i = 0; i < k; i++) {
+                x[i] = i;
+            }
+            for (int i = 0; i < n; i++) {
+                int 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.test/src/com/oracle/truffle/r/test/ExpectedTestOutput.test b/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/ExpectedTestOutput.test
index fecef64a4a..b57be5195c 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
@@ -112800,6 +112800,55 @@ In dweibull(0, Inf, 0.5) : NaNs produced
  [7] -11.5068528 -19.3068528        -Inf        -Inf   0.6931472   0.6931472
 [13]        -Inf         NaN
 
+##com.oracle.truffle.r.test.library.stats.TestDistributions.testDensityFunctions#Output.MayIgnoreWarningContext#
+#dwilcox(0, -Inf,  10)
+[1] NaN
+Warning message:
+In dwilcox(0, -Inf, 10) : NaNs produced
+
+##com.oracle.truffle.r.test.library.stats.TestDistributions.testDensityFunctions#Output.MayIgnoreWarningContext#
+#dwilcox(0, 10, -Inf)
+[1] NaN
+Warning message:
+In dwilcox(0, 10, -Inf) : NaNs produced
+
+##com.oracle.truffle.r.test.library.stats.TestDistributions.testDensityFunctions#Output.MayIgnoreWarningContext#
+#dwilcox(0, 10, Inf)
+[1] NaN
+Warning message:
+In dwilcox(0, 10, Inf) : NaNs produced
+
+##com.oracle.truffle.r.test.library.stats.TestDistributions.testDensityFunctions#Output.MayIgnoreWarningContext#
+#dwilcox(0, 10, NaN)
+[1] NaN
+
+##com.oracle.truffle.r.test.library.stats.TestDistributions.testDensityFunctions#Output.MayIgnoreWarningContext#
+#dwilcox(0, Inf,  10)
+[1] 0
+
+##com.oracle.truffle.r.test.library.stats.TestDistributions.testDensityFunctions#Output.MayIgnoreWarningContext#
+#dwilcox(0, NaN,  10)
+[1] NaN
+
+##com.oracle.truffle.r.test.library.stats.TestDistributions.testDensityFunctions#Output.MayIgnoreWarningContext#
+#dwilcox(c(1, 3, 5, 100, 1000), 4, 7, log=F)
+[1] 0.003030303 0.009090909 0.018181818 0.000000000 0.000000000
+
+##com.oracle.truffle.r.test.library.stats.TestDistributions.testDensityFunctions#Output.MayIgnoreWarningContext#
+#dwilcox(c(1, 3, 5, 100, 1000), 4, 7, log=T)
+[1] -5.799093 -4.700480 -4.007333      -Inf      -Inf
+
+##com.oracle.truffle.r.test.library.stats.TestDistributions.testDensityFunctions#Output.MayIgnoreWarningContext#
+#dwilcox(c(1, 3, 5, 100, 1000, -Inf, -0.42e-30, 0, 0.42e-30, Inf, NaN), 10, 10, log=F)
+ [1] 5.412544e-06 1.623763e-05 3.788781e-05 5.412544e-06 0.000000e+00
+ [6] 0.000000e+00 5.412544e-06 5.412544e-06 5.412544e-06 0.000000e+00
+[11]          NaN
+
+##com.oracle.truffle.r.test.library.stats.TestDistributions.testDensityFunctions#Output.MayIgnoreWarningContext#
+#dwilcox(c(1, 3, 5, 100, 1000, -Inf, -0.42e-30, 0, 0.42e-30, Inf, NaN), 10, 10, log=T)
+ [1] -12.12679 -11.02818 -10.18088 -12.12679      -Inf      -Inf -12.12679
+ [8] -12.12679 -12.12679      -Inf       NaN
+
 ##com.oracle.truffle.r.test.library.stats.TestDistributions.testDistributionFunctions#Output.MayIgnoreWarningContext#
 #pbeta(0, -1,  0.5)
 [1] NaN
@@ -114466,6 +114515,76 @@ In pweibull(0, 1, 0) : NaNs produced
  [6] -6.144231e-06 -5.030468e-06 -2.061154e-09          -Inf          -Inf
 [11]          -Inf -6.925191e+01  0.000000e+00           NaN
 
+##com.oracle.truffle.r.test.library.stats.TestDistributions.testDistributionFunctions#Output.MayIgnoreWarningContext#
+#pwilcox(0, -Inf,  10)
+[1] NaN
+Warning message:
+In pwilcox(0, -Inf, 10) : NaNs produced
+
+##com.oracle.truffle.r.test.library.stats.TestDistributions.testDistributionFunctions#Output.MayIgnoreWarningContext#
+#pwilcox(0, 10, -Inf)
+[1] NaN
+Warning message:
+In pwilcox(0, 10, -Inf) : NaNs produced
+
+##com.oracle.truffle.r.test.library.stats.TestDistributions.testDistributionFunctions#Output.MayIgnoreWarningContext#
+#pwilcox(0, 10, Inf)
+[1] NaN
+Warning message:
+In pwilcox(0, 10, Inf) : NaNs produced
+
+##com.oracle.truffle.r.test.library.stats.TestDistributions.testDistributionFunctions#Output.MayIgnoreWarningContext#
+#pwilcox(0, 10, NaN)
+[1] NaN
+
+##com.oracle.truffle.r.test.library.stats.TestDistributions.testDistributionFunctions#Output.MayIgnoreWarningContext#
+#pwilcox(0, Inf,  10)
+[1] NaN
+Warning message:
+In pwilcox(0, Inf, 10) : NaNs produced
+
+##com.oracle.truffle.r.test.library.stats.TestDistributions.testDistributionFunctions#Output.MayIgnoreWarningContext#
+#pwilcox(0, NaN,  10)
+[1] NaN
+
+##com.oracle.truffle.r.test.library.stats.TestDistributions.testDistributionFunctions#Output.MayIgnoreWarningContext#
+#pwilcox(c(1, 3, 5, 100, 1000), 4, 7, lower.tail=F, log.p=F)
+[1] 0.9939394 0.9787879 0.9454545 0.0000000 0.0000000
+
+##com.oracle.truffle.r.test.library.stats.TestDistributions.testDistributionFunctions#Output.MayIgnoreWarningContext#
+#pwilcox(c(1, 3, 5, 100, 1000), 4, 7, lower.tail=F, log.p=T)
+[1] -0.006079046 -0.021440331 -0.056089467         -Inf         -Inf
+
+##com.oracle.truffle.r.test.library.stats.TestDistributions.testDistributionFunctions#Output.MayIgnoreWarningContext#
+#pwilcox(c(1, 3, 5, 100, 1000), 4, 7, lower.tail=T, log.p=F)
+[1] 0.006060606 0.021212121 0.054545455 1.000000000 1.000000000
+
+##com.oracle.truffle.r.test.library.stats.TestDistributions.testDistributionFunctions#Output.MayIgnoreWarningContext#
+#pwilcox(c(1, 3, 5, 100, 1000), 4, 7, lower.tail=T, log.p=T)
+[1] -5.105945 -3.853183 -2.908721  0.000000  0.000000
+
+##com.oracle.truffle.r.test.library.stats.TestDistributions.testDistributionFunctions#Output.MayIgnoreWarningContext#
+#pwilcox(c(1, 3, 5, 100, 1000, -Inf, -0.42e-30, 0, 0.42e-30, Inf, NaN), 10, 10, lower.tail=F, log.p=F)
+ [1] 0.9999892 0.9999621 0.9998972 0.0000000 0.0000000 1.0000000 0.9999946
+ [8] 0.9999946 0.9999946 0.0000000       NaN
+
+##com.oracle.truffle.r.test.library.stats.TestDistributions.testDistributionFunctions#Output.MayIgnoreWarningContext#
+#pwilcox(c(1, 3, 5, 100, 1000, -Inf, -0.42e-30, 0, 0.42e-30, Inf, NaN), 10, 10, lower.tail=F, log.p=T)
+ [1] -1.082515e-05 -3.788853e-05 -1.028436e-04          -Inf          -Inf
+ [6]  0.000000e+00 -5.412559e-06 -5.412559e-06 -5.412559e-06          -Inf
+[11]           NaN
+
+##com.oracle.truffle.r.test.library.stats.TestDistributions.testDistributionFunctions#Output.MayIgnoreWarningContext#
+#pwilcox(c(1, 3, 5, 100, 1000, -Inf, -0.42e-30, 0, 0.42e-30, Inf, NaN), 10, 10, lower.tail=T, log.p=F)
+ [1] 1.082509e-05 3.788781e-05 1.028383e-04 1.000000e+00 1.000000e+00
+ [6] 0.000000e+00 5.412544e-06 5.412544e-06 5.412544e-06 1.000000e+00
+[11]          NaN
+
+##com.oracle.truffle.r.test.library.stats.TestDistributions.testDistributionFunctions#Output.MayIgnoreWarningContext#
+#pwilcox(c(1, 3, 5, 100, 1000, -Inf, -0.42e-30, 0, 0.42e-30, Inf, NaN), 10, 10, lower.tail=T, log.p=T)
+ [1] -11.433644 -10.180881  -9.182352   0.000000   0.000000       -Inf
+ [7] -12.126791 -12.126791 -12.126791   0.000000        NaN
+
 ##com.oracle.truffle.r.test.library.stats.TestDistributions.testQuantileFunctions#Output.MayIgnoreWarningContext#
 #qbeta(-0.42e-38, 0.5, 0.5)
 [1] NaN
@@ -116558,6 +116677,110 @@ In qweibull(Inf, 1, 0.5) : NaNs produced
 #qweibull(log(c(0, 42e-80, 0.1, 0.5, 0.7, 1-42e-80, 1)), 1e100, 1, lower.tail=T, log.p=T)
 [1]   0   1   1   1   1 Inf Inf
 
+##com.oracle.truffle.r.test.library.stats.TestDistributions.testQuantileFunctions#Output.MayIgnoreWarningContext#
+#qwilcox(-0.42e-38, 10, 10)
+[1] NaN
+Warning message:
+In qwilcox(-4.2e-39, 10, 10) : NaNs produced
+
+##com.oracle.truffle.r.test.library.stats.TestDistributions.testQuantileFunctions#Output.MayIgnoreWarningContext#
+#qwilcox(-42, 10, 10)
+[1] NaN
+Warning message:
+In qwilcox(-42, 10, 10) : NaNs produced
+
+##com.oracle.truffle.r.test.library.stats.TestDistributions.testQuantileFunctions#Output.MayIgnoreWarningContext#
+#qwilcox(-Inf, 10, 10)
+[1] NaN
+Warning message:
+In qwilcox(-Inf, 10, 10) : NaNs produced
+
+##com.oracle.truffle.r.test.library.stats.TestDistributions.testQuantileFunctions#Output.MayIgnoreWarningContext#
+#qwilcox(0, -Inf,  10)
+[1] NaN
+Warning message:
+In qwilcox(0, -Inf, 10) : NaNs produced
+
+##com.oracle.truffle.r.test.library.stats.TestDistributions.testQuantileFunctions#Output.MayIgnoreWarningContext#
+#qwilcox(0, 10, -Inf)
+[1] NaN
+Warning message:
+In qwilcox(0, 10, -Inf) : NaNs produced
+
+##com.oracle.truffle.r.test.library.stats.TestDistributions.testQuantileFunctions#Output.MayIgnoreWarningContext#
+#qwilcox(0, 10, Inf)
+[1] NaN
+Warning message:
+In qwilcox(0, 10, Inf) : NaNs produced
+
+##com.oracle.truffle.r.test.library.stats.TestDistributions.testQuantileFunctions#Output.MayIgnoreWarningContext#
+#qwilcox(0, 10, NaN)
+[1] NaN
+
+##com.oracle.truffle.r.test.library.stats.TestDistributions.testQuantileFunctions#Output.MayIgnoreWarningContext#
+#qwilcox(0, Inf,  10)
+[1] NaN
+Warning message:
+In qwilcox(0, Inf, 10) : NaNs produced
+
+##com.oracle.truffle.r.test.library.stats.TestDistributions.testQuantileFunctions#Output.MayIgnoreWarningContext#
+#qwilcox(0, NaN,  10)
+[1] NaN
+
+##com.oracle.truffle.r.test.library.stats.TestDistributions.testQuantileFunctions#Output.MayIgnoreWarningContext#
+#qwilcox(Inf, 10, 10)
+[1] NaN
+Warning message:
+In qwilcox(Inf, 10, 10) : NaNs produced
+
+##com.oracle.truffle.r.test.library.stats.TestDistributions.testQuantileFunctions#Output.MayIgnoreWarningContext#
+#qwilcox(NaN, 10, 10)
+[1] NaN
+
+##com.oracle.truffle.r.test.library.stats.TestDistributions.testQuantileFunctions#Output.MayIgnoreWarningContext#
+#qwilcox(c(0, 42e-80, 0.1, 0.5, 0.7, 1-42e-80, 1), 10, 10, lower.tail=F, log.p=F)
+[1] 100 100  67  50  43   0   0
+
+##com.oracle.truffle.r.test.library.stats.TestDistributions.testQuantileFunctions#Output.MayIgnoreWarningContext#
+#qwilcox(c(0, 42e-80, 0.1, 0.5, 0.7, 1-42e-80, 1), 10, 10, lower.tail=T, log.p=F)
+[1]   0   0  33  50  57 100 100
+
+##com.oracle.truffle.r.test.library.stats.TestDistributions.testQuantileFunctions#Output.MayIgnoreWarningContext#
+#qwilcox(c(0, 42e-80, 0.1, 0.5, 0.7, 1-42e-80, 1), 4, 7, lower.tail=F, log.p=F)
+[1] 28 28 21 14 11  0  0
+
+##com.oracle.truffle.r.test.library.stats.TestDistributions.testQuantileFunctions#Output.MayIgnoreWarningContext#
+#qwilcox(c(0, 42e-80, 0.1, 0.5, 0.7, 1-42e-80, 1), 4, 7, lower.tail=T, log.p=F)
+[1]  0  0  7 14 17 28 28
+
+##com.oracle.truffle.r.test.library.stats.TestDistributions.testQuantileFunctions#Output.MayIgnoreWarningContext#
+#qwilcox(log(c(0, 42e-80, 0.1, 0.5, 0.7, 1-42e-80, 1)), 10, 10, lower.tail=F, log.p=T)
+[1] NaN 100  67  50  43   0   0
+Warning message:
+In qwilcox(log(c(0, 4.2e-79, 0.1, 0.5, 0.7, 1 - 4.2e-79, 1)), 10,  :
+  NaNs produced
+
+##com.oracle.truffle.r.test.library.stats.TestDistributions.testQuantileFunctions#Output.MayIgnoreWarningContext#
+#qwilcox(log(c(0, 42e-80, 0.1, 0.5, 0.7, 1-42e-80, 1)), 10, 10, lower.tail=T, log.p=T)
+[1] NaN   0  33  50  57 100 100
+Warning message:
+In qwilcox(log(c(0, 4.2e-79, 0.1, 0.5, 0.7, 1 - 4.2e-79, 1)), 10,  :
+  NaNs produced
+
+##com.oracle.truffle.r.test.library.stats.TestDistributions.testQuantileFunctions#Output.MayIgnoreWarningContext#
+#qwilcox(log(c(0, 42e-80, 0.1, 0.5, 0.7, 1-42e-80, 1)), 4, 7, lower.tail=F, log.p=T)
+[1] NaN  28  21  14  11   0   0
+Warning message:
+In qwilcox(log(c(0, 4.2e-79, 0.1, 0.5, 0.7, 1 - 4.2e-79, 1)), 4,  :
+  NaNs produced
+
+##com.oracle.truffle.r.test.library.stats.TestDistributions.testQuantileFunctions#Output.MayIgnoreWarningContext#
+#qwilcox(log(c(0, 42e-80, 0.1, 0.5, 0.7, 1-42e-80, 1)), 4, 7, lower.tail=T, log.p=T)
+[1] NaN   0   7  14  17  28  28
+Warning message:
+In qwilcox(log(c(0, 4.2e-79, 0.1, 0.5, 0.7, 1 - 4.2e-79, 1)), 4,  :
+  NaNs produced
+
 ##com.oracle.truffle.r.test.library.stats.TestExternal_covcor.testCovcor#
 #.Call(stats:::C_cov, 1:5, 1:5, 4, FALSE)
 [1] 2.5
@@ -116634,7 +116857,7 @@ In rbinom("aa", 10, 0.5) : NAs introduced by coercion
 #set.seed(42); rbinom(c(1,2), 11:12, c(0.1, 0.5, 0.9))
 [1] 3 9
 
-##com.oracle.truffle.r.test.library.stats.TestExternal_rnbinom.testRbinomWithMu#
+##com.oracle.truffle.r.test.library.stats.TestExternal_rnbinom.testRbinomWithMu#Output.IgnoreWarningContext#
 #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
diff --git a/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/library/stats/TestDistributions.java b/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/library/stats/TestDistributions.java
index 3013893dbe..6917112ebe 100644
--- a/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/library/stats/TestDistributions.java
+++ b/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/library/stats/TestDistributions.java
@@ -143,7 +143,11 @@ public class TestDistributions extends TestBase {
                     addErrorParamValues("-3.3", "0").
                     test("1, 0.5", withDefaultQ("1", "2", "3.3", "4", "5", "6", "6.1", "10")).
                     test("0.5, 10", withQuantiles("1", "2", "3.3", "4", "5", "6", "6.1", "10")).
-                    test("1e100, 1", withQuantiles("0.9", "0.99999999999999999", "1-1e-30", "1"))
+                    test("1e100, 1", withQuantiles("0.9", "0.99999999999999999", "1-1e-30", "1")),
+            // Note: wilcox is very memory consuming, so we test only small argument values here
+            distr("wilcox").
+                    test("10, 10", withDefaultQ("1", "3", "5", "100", "1000")).
+                    test("4, 7", withQuantiles("1", "3", "5", "100", "1000"))
     };
     // @formatter:on
 
diff --git a/mx.fastr/copyrights/overrides b/mx.fastr/copyrights/overrides
index 2253a4e635..df3d2df47d 100644
--- a/mx.fastr/copyrights/overrides
+++ b/mx.fastr/copyrights/overrides
@@ -28,82 +28,83 @@ com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/grDevices/pdf/PdfG
 com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/grid/GridFunctions.java,gnu_r_murrel_core.copyright
 com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/methods/MethodsListDispatch.java,gnu_r.copyright
 com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/methods/Slot.java,gnu_r.copyright
-com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/stats/Arithmetic.java,gnu_r_gentleman_ihaka.copyright
-com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/stats/DNorm.java,gnu_r.copyright
-com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/stats/RBeta.java,gnu_r_gentleman_ihaka.copyright
-com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/stats/RMultinom.java,gnu_r_gentleman_ihaka.copyright
-com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/stats/Cauchy.java,gnu_r_ihaka_core.copyright
+com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/nmath/Arithmetic.java,gnu_r_gentleman_ihaka.copyright
+com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/nmath/distr/DNorm.java,gnu_r.copyright
+com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/nmath/distr/RBeta.java,gnu_r_gentleman_ihaka.copyright
+com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/nmath/distr/RMultinom.java,gnu_r_gentleman_ihaka.copyright
+com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/nmath/distr/Cauchy.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/RandFunctionsNodes.java,gnu_r_gentleman_ihaka.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/RNBinom.java,gnu_r_ihaka_core.copyright
-com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/stats/PNBinom.java,gnu_r_ihaka_core.copyright
-com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/stats/DNBinom.java,gnu_r.core.copyright
+com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/stats/RMultinomNode.java,gnu_r_gentleman_ihaka.copyright
+com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/nmath/distr/Signrank.java,gnu_r.core.copyright
+com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/nmath/distr/Dbinom.java,gnu_r.copyright
+com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/nmath/distr/RNBinom.java,gnu_r_ihaka_core.copyright
+com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/nmath/distr/PNBinom.java,gnu_r_ihaka_core.copyright
+com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/nmath/distr/DNBinom.java,gnu_r.core.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/QHyper.java,gnu_r_ihaka_core.copyright
-com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/stats/DHyper.java,gnu_r.core.copyright
-com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/stats/PHyper.java,gnu_r_ihaka.copyright
-com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/stats/Qt.java,gnu_r_ihaka.copyright
-com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/stats/Pt.java,gnu_r_scan.copyright
-com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/stats/RHyper.java,gnu_r_ihaka.copyright
-com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/stats/MathInit.java,gnu_r.core.copyright
-com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/stats/Pbeta.java,gnu_r.core.copyright
-com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/stats/PNBeta.java,gnu_r.core.copyright
-com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/stats/QNBeta.java,gnu_r.core.copyright
-com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/stats/Qnf.java,gnu_r.core.copyright
-com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/stats/Dnf.java,gnu_r.core.copyright
-com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/stats/DNBeta.java,gnu_r_ihaka_core.copyright
-com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/stats/LBeta.java,gnu_r_ihaka.copyright
-com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/stats/Pbinom.java,gnu_r_ihaka.copyright
-com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/stats/Pf.java,gnu_r_ihaka_core.copyright
-com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/stats/Pnorm.java,gnu_r_ihaka.copyright
-com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/stats/PPois.java,gnu_r_ihaka_core.copyright
-com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/stats/QPois.java,gnu_r_ihaka_core.copyright
-com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/stats/QBeta.java,gnu_r_scan.copyright
-com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/stats/Qf.java,gnu_r_ihaka.copyright
-com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/stats/Qbinom.java,gnu_r_ihaka.copyright
-com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/stats/Qnorm.java,gnu_r_ihaka.copyright
-com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/stats/Random2.java,gnu_r.copyright
-com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/stats/RPois.java,gnu_r_ihaka_core.copyright
-com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/stats/Rbinom.java,gnu_r_ihaka.copyright
-com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/stats/Unif.java,gnu_r_ihaka_core.copyright
-com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/stats/Rnorm.java,gnu_r.copyright
-com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/stats/Chisq.java,gnu_r_ihaka_core.copyright
-com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/stats/PNChisq.java,gnu_r.copyright
-com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/stats/QNChisq.java,gnu_r_gentleman_ihaka.copyright
-com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/stats/DNChisq.java,gnu_r_ihaka.copyright
+com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/nmath/DPQ.java,gnu_r.core.copyright
+com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/nmath/distr/Rt.java,gnu_r_ihaka_core.copyright
+com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/nmath/GammaFunctions.java,gnu_r_qgamma.copyright
+com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/nmath/distr/QHyper.java,gnu_r_ihaka_core.copyright
+com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/nmath/distr/DHyper.java,gnu_r.core.copyright
+com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/nmath/distr/PHyper.java,gnu_r_ihaka.copyright
+com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/nmath/distr/Qt.java,gnu_r_ihaka.copyright
+com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/nmath/distr/Pt.java,gnu_r_scan.copyright
+com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/nmath/distr/RHyper.java,gnu_r_ihaka.copyright
+com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/nmath/distr/Pbeta.java,gnu_r.core.copyright
+com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/nmath/distr/PNBeta.java,gnu_r.core.copyright
+com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/nmath/distr/QNBeta.java,gnu_r.core.copyright
+com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/nmath/distr/Qnf.java,gnu_r.core.copyright
+com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/nmath/distr/Dnf.java,gnu_r.core.copyright
+com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/nmath/distr/DNBeta.java,gnu_r_ihaka_core.copyright
+com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/nmath/LBeta.java,gnu_r_ihaka.copyright
+com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/nmath/distr/Pbinom.java,gnu_r_ihaka.copyright
+com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/nmath/distr/Pf.java,gnu_r_ihaka_core.copyright
+com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/nmath/distr/Pnorm.java,gnu_r_ihaka.copyright
+com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/nmath/distr/PPois.java,gnu_r_ihaka_core.copyright
+com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/nmath/distr/QPois.java,gnu_r_ihaka_core.copyright
+com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/nmath/distr/QBeta.java,gnu_r_scan.copyright
+com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/nmath/distr/Qf.java,gnu_r_ihaka.copyright
+com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/nmath/distr/Qbinom.java,gnu_r_ihaka.copyright
+com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/nmath/distr/Qnorm.java,gnu_r_ihaka.copyright
+com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/nmath/distr/RPois.java,gnu_r_ihaka_core.copyright
+com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/nmath/distr/Rbinom.java,gnu_r_ihaka.copyright
+com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/nmath/distr/Unif.java,gnu_r_ihaka_core.copyright
+com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/nmath/distr/Rnorm.java,gnu_r.copyright
+com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/nmath/distr/Chisq.java,gnu_r_ihaka_core.copyright
+com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/nmath/distr/PNChisq.java,gnu_r.copyright
+com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/nmath/distr/QNChisq.java,gnu_r_gentleman_ihaka.copyright
+com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/nmath/distr/DNChisq.java,gnu_r_ihaka.copyright
 com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/stats/SplineFunctions.java,gnu_r_splines.copyright
-com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/stats/StatsFunctions.java,gnu_r_gentleman_ihaka.copyright
-com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/stats/RandGenerationFunctions.java,gnu_r_gentleman_ihaka.copyright
-com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/stats/RMath.java,gnu_r_ihaka.copyright
-com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/stats/QuantileSearch.java,gnu_r_ihaka.copyright
-com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/stats/QNBinom.java,gnu_r_ihaka.copyright
-com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/stats/RMathError.java,gnu_r.core.copyright
-com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/stats/LogNormal.java,gnu_r_ihaka.copyright
-com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/stats/MathConstants.java,gnu_r_ihaka.copyright
-com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/stats/TOMS708.java,gnu_r.copyright
-com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/stats/SNorm.java,gnu_r_ihaka_core.copyright
-com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/stats/SExp.java,gnu_r_ihaka_core.copyright
-com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/stats/RGamma.java,gnu_r_ihaka_core.copyright
-com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/stats/PGamma.java,gnu_r_welinder.copyright
-com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/stats/Logis.java,gnu_r_ihaka_core.copyright
-com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/stats/Pnf.java,gnu_r_ihaka_core.copyright
-com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/stats/Rf.java,gnu_r_ihaka_core.copyright
-com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/stats/Exp.java,gnu_r_ihaka_core.copyright
-com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/stats/Geom.java,gnu_r_ihaka_core.copyright
-com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/stats/Dt.java,gnu_r.core.copyright
-com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/stats/Df.java,gnu_r.core.copyright
-com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/stats/DBeta.java,gnu_r.core.copyright
-com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/stats/DPois.java,gnu_r.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/Weibull.java,gnu_r_ihaka_core.copyright
+com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/stats/StatsFunctionsNodes.java,gnu_r_gentleman_ihaka.copyright
+com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/nmath/RMath.java,gnu_r_ihaka.copyright
+com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/nmath/distr/QuantileSearch.java,gnu_r_ihaka.copyright
+com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/nmath/distr/QNBinom.java,gnu_r_ihaka.copyright
+com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/nmath/RMathError.java,gnu_r.core.copyright
+com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/nmath/Choose.java,gnu_r.copyright
+com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/nmath/Mach.java,gnu_r_ihaka_core.copyright
+com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/nmath/distr/LogNormal.java,gnu_r_ihaka.copyright
+com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/nmath/MathConstants.java,gnu_r_ihaka.copyright
+com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/nmath/TOMS708.java,gnu_r.copyright
+com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/nmath/distr/SNorm.java,gnu_r_ihaka_core.copyright
+com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/nmath/distr/SExp.java,gnu_r_ihaka_core.copyright
+com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/nmath/distr/RGamma.java,gnu_r_ihaka_core.copyright
+com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/nmath/distr/PGamma.java,gnu_r_welinder.copyright
+com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/nmath/distr/Logis.java,gnu_r_ihaka_core.copyright
+com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/nmath/distr/Pnf.java,gnu_r_ihaka_core.copyright
+com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/nmath/distr/Rf.java,gnu_r_ihaka_core.copyright
+com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/nmath/distr/Exp.java,gnu_r_ihaka_core.copyright
+com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/nmath/distr/Geom.java,gnu_r_ihaka_core.copyright
+com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/nmath/distr/Dt.java,gnu_r.core.copyright
+com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/nmath/distr/Df.java,gnu_r.core.copyright
+com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/nmath/distr/DBeta.java,gnu_r.core.copyright
+com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/nmath/distr/DPois.java,gnu_r.core.copyright
+com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/nmath/distr/RNchisq.java,gnu_r.copyright
+com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/nmath/distr/Wilcox.java,gnu_r.core.copyright
+com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/nmath/distr/Weibull.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
-- 
GitLab