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 05f4194085e2defdd2ebb9174d123c9efc7dc5d5..de74bbaa12896b6f15044afdb7da4d79709bf5af 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
@@ -258,7 +258,9 @@ 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(ChooseBuiltin.class, ChooseBuiltinNodeGen::create);
+        add(ChooseFunctions.Choose.class, ChooseFunctionsFactory.ChooseNodeGen::create);
+        add(ChooseFunctions.LChoose.class, ChooseFunctionsFactory.LChooseNodeGen::create);
+        add(BetaFunctions.LBeta.class, BetaFunctionsFactory.LBetaNodeGen::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/BetaFunctions.java b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/BetaFunctions.java
new file mode 100644
index 0000000000000000000000000000000000000000..c67e53a67541901595fcd9967e20eeb2a8d6804b
--- /dev/null
+++ b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/BetaFunctions.java
@@ -0,0 +1,99 @@
+/*
+ * 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
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package com.oracle.truffle.r.nodes.builtin.base;
+
+import static com.oracle.truffle.r.nodes.builtin.CastBuilder.Predef.asIntegerVector;
+import static com.oracle.truffle.r.nodes.builtin.CastBuilder.Predef.logicalValue;
+import static com.oracle.truffle.r.nodes.builtin.CastBuilder.Predef.numericValue;
+import static com.oracle.truffle.r.runtime.builtins.RBehavior.PURE;
+import static com.oracle.truffle.r.runtime.builtins.RBuiltinKind.INTERNAL;
+
+import com.oracle.truffle.api.dsl.Cached;
+import com.oracle.truffle.api.dsl.Specialization;
+import com.oracle.truffle.r.nodes.attributes.UnaryCopyAttributesNode;
+import com.oracle.truffle.r.nodes.builtin.RBuiltinNode;
+import com.oracle.truffle.r.runtime.RError.Message;
+import com.oracle.truffle.r.runtime.RRuntime;
+import com.oracle.truffle.r.runtime.builtins.RBuiltin;
+import com.oracle.truffle.r.runtime.data.RDataFactory.VectorFactory;
+import com.oracle.truffle.r.runtime.data.RDoubleVector;
+import com.oracle.truffle.r.runtime.data.model.RAbstractDoubleVector;
+import com.oracle.truffle.r.runtime.data.model.RAbstractVector;
+import com.oracle.truffle.r.runtime.data.nodes.VectorAccess;
+import com.oracle.truffle.r.runtime.data.nodes.VectorAccess.SequentialIterator;
+
+/**
+ * Base package builtins beta and lbeta.
+ */
+public class BetaFunctions {
+
+    @RBuiltin(name = "lbeta", kind = INTERNAL, parameterNames = {"a", "b"}, behavior = PURE)
+    public abstract static class LBeta extends RBuiltinNode.Arg2 {
+
+        static {
+            Casts casts = new Casts(LBeta.class);
+            casts.arg(0).mustBe(numericValue(), Message.NON_NUMERIC_MATH).mapIf(logicalValue(), asIntegerVector());
+            casts.arg(1).mustBe(numericValue(), Message.NON_NUMERIC_MATH).mapIf(logicalValue(), asIntegerVector());
+        }
+
+        @Child private UnaryCopyAttributesNode copyAttrs = UnaryCopyAttributesNode.create();
+
+        @Specialization(guards = {"aAccess.supports(a)", "bAccess.supports(b)"})
+        protected RAbstractDoubleVector doVectors(RAbstractVector a, RAbstractVector b,
+                        @Cached("a.access()") VectorAccess aAccess,
+                        @Cached("b.access()") VectorAccess bAccess,
+                        @Cached("create()") VectorFactory factory) {
+            try (SequentialIterator aIter = aAccess.access(a); SequentialIterator bIter = bAccess.access(b)) {
+                int resultLen = Math.max(aAccess.getLength(aIter), bAccess.getLength(bIter));
+                double[] result = new double[resultLen];
+                for (int i = 0; i < resultLen; i++) {
+                    aAccess.nextWithWrap(aIter);
+                    bAccess.nextWithWrap(bIter);
+                    result[i] = lbeta(aAccess.getDouble(aIter), bAccess.getDouble(bIter));
+                }
+                RDoubleVector resultVector = factory.createDoubleVector(result, a.isComplete() && b.isComplete());
+                if (resultLen == aAccess.getLength(aIter)) {
+                    copyAttrs.execute(resultVector, a);
+                } else {
+                    copyAttrs.execute(resultVector, b);
+                }
+                return resultVector;
+            }
+        }
+
+        @Specialization(replaces = "doVectors")
+        protected RAbstractDoubleVector doVectorsGeneric(RAbstractVector a, RAbstractVector b,
+                        @Cached("create()") VectorFactory factory) {
+            return doVectors(a, b, a.slowPathAccess(), b.slowPathAccess(), factory);
+        }
+
+        private double lbeta(double a, double b) {
+            if (RRuntime.isNA(a) || RRuntime.isNA(b)) {
+                return RRuntime.DOUBLE_NA;
+            }
+            return com.oracle.truffle.r.runtime.nmath.LBeta.lbeta(a, b);
+        }
+
+    }
+
+}
diff --git a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/ChooseBuiltin.java b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/ChooseBuiltin.java
deleted file mode 100644
index ce3302739953a210f01e316de63d8cb28eb8e917..0000000000000000000000000000000000000000
--- a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/ChooseBuiltin.java
+++ /dev/null
@@ -1,119 +0,0 @@
-/*
- * 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
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-package com.oracle.truffle.r.nodes.builtin.base;
-
-import static com.oracle.truffle.r.nodes.builtin.CastBuilder.Predef.asIntegerVector;
-import static com.oracle.truffle.r.nodes.builtin.CastBuilder.Predef.logicalValue;
-import static com.oracle.truffle.r.nodes.builtin.CastBuilder.Predef.numericValue;
-import static com.oracle.truffle.r.runtime.builtins.RBehavior.PURE;
-import static com.oracle.truffle.r.runtime.builtins.RBuiltinKind.INTERNAL;
-
-import java.util.function.IntToDoubleFunction;
-import java.util.function.IntUnaryOperator;
-
-import com.oracle.truffle.api.dsl.Specialization;
-import com.oracle.truffle.r.nodes.builtin.RBuiltinNode;
-import com.oracle.truffle.r.runtime.RError.Message;
-import com.oracle.truffle.r.runtime.RRuntime;
-import com.oracle.truffle.r.runtime.Utils;
-import com.oracle.truffle.r.runtime.builtins.RBuiltin;
-import com.oracle.truffle.r.runtime.data.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 ChooseBuiltin extends RBuiltinNode.Arg2 {
-
-    private final NACheck na = NACheck.create();
-
-    static {
-        Casts casts = new Casts(ChooseBuiltin.class);
-        casts.arg("n").mustBe(numericValue(), Message.NON_NUMERIC_MATH).mapIf(logicalValue(), asIntegerVector());
-        casts.arg("k").mustBe(numericValue(), Message.NON_NUMERIC_MATH).mapIf(logicalValue(), asIntegerVector());
-    }
-
-    @Specialization
-    protected RAbstractDoubleVector doInts(RAbstractIntVector n, RAbstractIntVector k) {
-        // Note: we may check overflow, return int vector if possible, otherwise specialize
-        // Note: may be useful to specialize on small n and k and do only integer arithmetic
-        return choose(n.getLength(), idx -> (double) n.getDataAt(idx), k.getLength(), idx -> k.getDataAt(idx));
-    }
-
-    @Specialization
-    protected RAbstractDoubleVector doDoubleInt(RAbstractDoubleVector n, RAbstractIntVector k) {
-        return choose(n.getLength(), idx -> n.getDataAt(idx), k.getLength(), idx -> k.getDataAt(idx));
-    }
-
-    // In the cases where 'k' is real vector we round values in 'k' to integers. Warning is shown
-    // only when the numbers indeed loose precision and is show for each such instance. For example,
-    // if k is two times shorter than n, for each non-integral value the warning will be shown
-    // twice.
-
-    @Specialization
-    protected RAbstractDoubleVector doIntDouble(RAbstractIntVector n, RAbstractDoubleVector k) {
-        return choose(n.getLength(), idx -> (double) n.getDataAt(idx), k.getLength(), idx -> castToInt(k, idx));
-    }
-
-    @Specialization
-    protected RAbstractDoubleVector doDoubles(RAbstractDoubleVector n, RAbstractDoubleVector k) {
-        return choose(n.getLength(), idx -> n.getDataAt(idx), k.getLength(), idx -> castToInt(k, idx));
-    }
-
-    private int castToInt(RAbstractDoubleVector k, int idx) {
-        double data = k.getDataAt(idx);
-        if (data == RRuntime.DOUBLE_NA) {
-            return RRuntime.INT_NA;
-        }
-
-        double result = Math.round(data);
-        if (result != data) {
-            warning(Message.CHOOSE_ROUNDING_WARNING, data, (int) result);
-        }
-        return (int) result;
-    }
-
-    private RAbstractDoubleVector choose(int nLength, IntToDoubleFunction getN, int kLength, IntUnaryOperator getK) {
-        int resultLen = Math.max(nLength, kLength);
-        double[] result = new double[resultLen];
-        na.enable(true);
-        for (int i = 0, nIdx = 0, kIdx = 0; i < resultLen; i++) {
-            result[i] = choose(getN.applyAsDouble(nIdx), getK.applyAsInt(kIdx));
-            na.check(result[i]);
-            nIdx = Utils.incMod(nIdx, nLength);
-            kIdx = Utils.incMod(kIdx, kLength);
-        }
-        return RDataFactory.createDoubleVector(result, na.neverSeenNA());
-    }
-
-    public static double choose(double n, int k) {
-        if (RRuntime.isNA(n) || RRuntime.isNA(k)) {
-            return RRuntime.DOUBLE_NA;
-        }
-        return Choose.choose(n, k);
-    }
-}
diff --git a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/ChooseFunctions.java b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/ChooseFunctions.java
new file mode 100644
index 0000000000000000000000000000000000000000..47f0609907f295b816a3711d22b4355c802a8ece
--- /dev/null
+++ b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/ChooseFunctions.java
@@ -0,0 +1,140 @@
+/*
+ * Copyright (c) 2017, 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.nodes.builtin.base;
+
+import static com.oracle.truffle.r.nodes.builtin.CastBuilder.Predef.asIntegerVector;
+import static com.oracle.truffle.r.nodes.builtin.CastBuilder.Predef.logicalValue;
+import static com.oracle.truffle.r.nodes.builtin.CastBuilder.Predef.numericValue;
+import static com.oracle.truffle.r.runtime.builtins.RBehavior.PURE;
+import static com.oracle.truffle.r.runtime.builtins.RBuiltinKind.INTERNAL;
+
+import com.oracle.truffle.api.dsl.Cached;
+import com.oracle.truffle.api.dsl.Specialization;
+import com.oracle.truffle.r.nodes.attributes.UnaryCopyAttributesNode;
+import com.oracle.truffle.r.nodes.builtin.RBuiltinNode;
+import com.oracle.truffle.r.runtime.RError.Message;
+import com.oracle.truffle.r.runtime.RRuntime;
+import com.oracle.truffle.r.runtime.RType;
+import com.oracle.truffle.r.runtime.builtins.RBuiltin;
+import com.oracle.truffle.r.runtime.data.RDataFactory.VectorFactory;
+import com.oracle.truffle.r.runtime.data.RDoubleVector;
+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.data.nodes.VectorAccess;
+import com.oracle.truffle.r.runtime.data.nodes.VectorAccess.SequentialIterator;
+
+public final class ChooseFunctions {
+
+    /**
+     * 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 static class Choose extends RBuiltinNode.Arg2 {
+
+        static {
+            Casts casts = new Casts(Choose.class);
+            casts.arg(0).mustBe(numericValue(), Message.NON_NUMERIC_MATH).mapIf(logicalValue(), asIntegerVector());
+            casts.arg(1).mustBe(numericValue(), Message.NON_NUMERIC_MATH).mapIf(logicalValue(), asIntegerVector());
+        }
+
+        @Child private UnaryCopyAttributesNode copyAttrs = UnaryCopyAttributesNode.create();
+
+        @Specialization(guards = {"nAccess.supports(n)", "kAccess.supports(k)"})
+        protected RAbstractDoubleVector doVectors(RAbstractVector n, RAbstractVector k,
+                        @Cached("n.access()") VectorAccess nAccess,
+                        @Cached("k.access()") VectorAccess kAccess,
+                        @Cached("create()") VectorFactory factory) {
+            try (SequentialIterator nIter = nAccess.access(n); SequentialIterator kIter = kAccess.access(k)) {
+                int resultLen = Math.max(nAccess.getLength(nIter), kAccess.getLength(kIter));
+                double[] result = new double[resultLen];
+                for (int i = 0; i < resultLen; i++) {
+                    nAccess.nextWithWrap(nIter);
+                    kAccess.nextWithWrap(kIter);
+                    result[i] = choose(nAccess.getDouble(nIter), (kAccess.getType() == RType.Integer) ? kAccess.getInt(kIter) : castToInt(kAccess.getDouble(kIter)));
+                }
+                RDoubleVector resultVector = factory.createDoubleVector(result, n.isComplete() && k.isComplete());
+                if (resultLen == nAccess.getLength(nIter)) {
+                    copyAttrs.execute(resultVector, n);
+                } else {
+                    copyAttrs.execute(resultVector, k);
+                }
+                return resultVector;
+            }
+        }
+
+        @Specialization(replaces = "doVectors")
+        protected RAbstractDoubleVector doVectorsGeneric(RAbstractIntVector n, RAbstractIntVector k,
+                        @Cached("create()") VectorFactory factory) {
+            return doVectors(n, k, n.slowPathAccess(), k.slowPathAccess(), factory);
+        }
+
+        private int castToInt(double data) {
+            // In the cases where 'k' is real vector we round values in 'k' to integers. Warning is
+            // shown only when the numbers indeed loose precision and is show for each such
+            // instance. For example, if k is two times shorter than n, for each non-integral value
+            // the warning will be shown twice.
+            if (data == RRuntime.DOUBLE_NA) {
+                return RRuntime.INT_NA;
+            }
+
+            double result = Math.round(data);
+            if (result != data) {
+                warning(Message.CHOOSE_ROUNDING_WARNING, data, (int) result);
+            }
+            return (int) result;
+        }
+
+        private double choose(double n, int k) {
+            if (RRuntime.isNA(n) || RRuntime.isNA(k)) {
+                return RRuntime.DOUBLE_NA;
+            }
+            return doChoose(n, k);
+        }
+
+        protected double doChoose(double n, int k) {
+            return com.oracle.truffle.r.runtime.nmath.Choose.choose(n, k);
+        }
+
+    }
+
+    /**
+     * Builtin lchoose with double n and integer k vector parameters.
+     */
+    @RBuiltin(name = "lchoose", kind = INTERNAL, parameterNames = {"n", "k"}, behavior = PURE)
+    public abstract static class LChoose extends Choose {
+
+        static {
+            Casts casts = new Casts(LChoose.class);
+            casts.arg(0).mustBe(numericValue(), Message.NON_NUMERIC_MATH).mapIf(logicalValue(), asIntegerVector());
+            casts.arg(1).mustBe(numericValue(), Message.NON_NUMERIC_MATH).mapIf(logicalValue(), asIntegerVector());
+        }
+
+        @Override
+        protected double doChoose(double n, int k) {
+            return com.oracle.truffle.r.runtime.nmath.Choose.lchoose(n, k);
+        }
+
+    }
+
+}
diff --git a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/builtin/InternalNode.java b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/builtin/InternalNode.java
index dbff8a0ce67e828259e1c9cca061c090ad62aeca..feef3ede00780b3cdcac6956f8df15e366ce5051 100644
--- a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/builtin/InternalNode.java
+++ b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/builtin/InternalNode.java
@@ -341,7 +341,7 @@ public abstract class InternalNode extends OperatorNode {
      */
     private static final List<String> NOT_IMPLEMENTED = Arrays.asList(
                     ".addTryHandlers", "interruptsSuspended", "restart", "backsolve", "max.col", "comment", "`comment<-`", "list2env", "tcrossprod",
-                    "lbeta", "beta", "lchoose", "dchisq", "pchisq", "qchisq", "dexp", "pexp", "qexp", "dgeom", "pgeom", "qgeom", "dpois", "ppois", "qpois", "dt", "pt", "qt", "dsignrank", "psignrank",
+                    "beta", "dchisq", "pchisq", "qchisq", "dexp", "pexp", "qexp", "dgeom", "pgeom", "qgeom", "dpois", "ppois", "qpois", "dt", "pt", "qt", "dsignrank", "psignrank",
                     "qsignrank", "besselJ", "besselY", "psigamma", "dbeta", "pbeta", "qbeta", "dbinom", "pbinom", "qbinom", "dcauchy", "pcauchy", "qcauchy", "df", "pf", "qf", "dgamma", "pgamma",
                     "qgamma", "dlnorm", "plnorm", "qlnorm", "dlogis", "plogis", "qlogis", "dnbinom", "pnbinom", "qnbinom", "dnorm", "pnorm", "qnorm", "dunif", "punif", "qunif", "dweibull", "pweibull",
                     "qweibull", "dnchisq", "pnchisq", "qnchisq", "dnt", "pnt", "qnt", "dwilcox", "pwilcox", "qwilcox", "besselI", "besselK", "dnbinom_mu", "pnbinom_mu", "qnbinom_mu", "dhyper",
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 478566456a1036954333be515326edf6188d38f0..71c091e5f81de87352a639664a550ccea7237616 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
@@ -14026,6 +14026,52 @@ Error: non-numeric argument to mathematical function
  [6]  0.027343750 -0.020507812  0.016113281 -0.013092041  0.010910034
 [11] -0.009273529
 
+##com.oracle.truffle.r.test.builtins.TestBuiltin_choose.testchoose4#Output.IgnoreWarningMessage#
+#.Internal(choose(0:2, 1.2))
+[1] 0 1 2
+Warning messages:
+1: 'k' (1.20) must be integer, rounded to 1
+2: 'k' (1.20) must be integer, rounded to 1
+3: 'k' (1.20) must be integer, rounded to 1
+
+##com.oracle.truffle.r.test.builtins.TestBuiltin_choose.testchoose4#Output.IgnoreWarningMessage#
+#.Internal(choose(2, 1.2))
+[1] 2
+Warning message:
+'k' (1.20) must be integer, rounded to 1
+
+##com.oracle.truffle.r.test.builtins.TestBuiltin_choose.testchoose4#
+#.Internal(choose(47, structure(array(21:24, dim=c(2,2)), dimnames=list(a=c('a1','a2'),b=c('b1','b2')))))
+    b
+a              b1          b2
+  a1 1.255176e+13 1.61238e+13
+  a2 1.483390e+13 1.61238e+13
+
+##com.oracle.truffle.r.test.builtins.TestBuiltin_choose.testchoose4#
+#.Internal(choose(structure(47, myattr='hello'), 2))
+[1] 1081
+attr(,"myattr")
+[1] "hello"
+
+##com.oracle.truffle.r.test.builtins.TestBuiltin_choose.testchoose4#
+#.Internal(choose(structure(array(21:24, dim=c(2,2)), dimnames=list(a=c('a1','a2'),b=c('b1','b2'))), 2))
+    b
+a     b1  b2
+  a1 210 253
+  a2 231 276
+
+##com.oracle.truffle.r.test.builtins.TestBuiltin_choose.testchooseWithLogical#
+#.Internal(choose(1, NA))
+[1] NA
+
+##com.oracle.truffle.r.test.builtins.TestBuiltin_choose.testchooseWithLogical#
+#.Internal(choose(FALSE, FALSE))
+[1] 1
+
+##com.oracle.truffle.r.test.builtins.TestBuiltin_choose.testchooseWithLogical#
+#.Internal(choose(NA, 1))
+[1] NA
+
 ##com.oracle.truffle.r.test.builtins.TestBuiltin_choose.testchooseWithLogical#
 #.Internal(choose(logical(0), logical(0)))
 numeric(0)
@@ -33034,15 +33080,75 @@ NULL
  1  2  3  4  5
 51 57 45 NA NA
 
-##com.oracle.truffle.r.test.builtins.TestBuiltin_lbeta.testlbeta1#Ignored.Unimplemented#
-#argv <- list(FALSE, FALSE); .Internal(lbeta(argv[[1]], argv[[2]]))
+##com.oracle.truffle.r.test.builtins.TestBuiltin_lbeta.testlbeta1#
+#.Internal(lbeta(47, structure(array(21:24, dim=c(2,2)), dimnames=list(a=c('a1','a2'),b=c('b1','b2')))))
+    b
+a           b1        b2
+  a1 -42.44874 -44.76679
+  a2 -43.62373 -45.87979
+
+##com.oracle.truffle.r.test.builtins.TestBuiltin_lbeta.testlbeta1#
+#.Internal(lbeta(structure(47, myattr='hello'), 2))
+[1] -7.721349
+attr(,"myattr")
+[1] "hello"
+
+##com.oracle.truffle.r.test.builtins.TestBuiltin_lbeta.testlbeta1#
+#.Internal(lbeta(structure(array(21:24, dim=c(2,2)), dimnames=list(a=c('a1','a2'),b=c('b1','b2'))), 2))
+    b
+a           b1        b2
+  a1 -6.135565 -6.313548
+  a2 -6.226537 -6.396930
+
+##com.oracle.truffle.r.test.builtins.TestBuiltin_lbeta.testlbeta1#
+#{ .Internal(lbeta(0:2, 2.2)) }
+[1]        Inf -0.7884574 -1.9516082
+
+##com.oracle.truffle.r.test.builtins.TestBuiltin_lbeta.testlbeta1#
+#{ .Internal(lbeta(1, NA)) }
+[1] NA
+
+##com.oracle.truffle.r.test.builtins.TestBuiltin_lbeta.testlbeta1#
+#{ .Internal(lbeta(1, NULL)) }
+Error: non-numeric argument to mathematical function
+
+##com.oracle.truffle.r.test.builtins.TestBuiltin_lbeta.testlbeta1#
+#{ .Internal(lbeta(2, 2.2)) }
+[1] -1.951608
+
+##com.oracle.truffle.r.test.builtins.TestBuiltin_lbeta.testlbeta1#
+#{ .Internal(lbeta(FALSE, FALSE)) }
 [1] Inf
 
-##com.oracle.truffle.r.test.builtins.TestBuiltin_lchoose.testlchoose1#Ignored.Unimplemented#
+##com.oracle.truffle.r.test.builtins.TestBuiltin_lbeta.testlbeta1#
+#{ .Internal(lbeta(NA, 1)) }
+[1] NA
+
+##com.oracle.truffle.r.test.builtins.TestBuiltin_lbeta.testlbeta1#
+#{ .Internal(lbeta(NULL, 1)) }
+Error: non-numeric argument to mathematical function
+
+##com.oracle.truffle.r.test.builtins.TestBuiltin_lbeta.testlbeta1#
+#{ .Internal(lbeta(c(2.2, 3.3), 2)) }
+[1] -1.951608 -2.652537
+
+##com.oracle.truffle.r.test.builtins.TestBuiltin_lbeta.testlbeta1#
+#{ .Internal(lbeta(c(2.2, 3.3), c(2,3,4))) }
+[1] -1.951608 -3.627097 -3.243592
+
+##com.oracle.truffle.r.test.builtins.TestBuiltin_lbeta.testlbeta1#
+#{ .Internal(lbeta(c(2.2, 3.3, 4.4), c(2,3))) }
+[1] -1.951608 -3.627097 -3.168003
+
+##com.oracle.truffle.r.test.builtins.TestBuiltin_lbeta.testlbeta1#
+#{ .Internal(lbeta(logical(0), logical(0))) }
+numeric(0)
+
+##com.oracle.truffle.r.test.builtins.TestBuiltin_lchoose.testlchoose1#
 #argv <- list(FALSE, FALSE); .Internal(lchoose(argv[[1]], argv[[2]]))
 [1] 0
 
-##com.oracle.truffle.r.test.builtins.TestBuiltin_lchoose.testlchoose2#Ignored.Unimplemented#
+##com.oracle.truffle.r.test.builtins.TestBuiltin_lchoose.testlchoose2#
 #argv <- list(50L, 0:48); .Internal(lchoose(argv[[1]], argv[[2]]))
  [1]  0.000000  3.912023  7.110696  9.883285 12.347138 14.566342 16.581245
  [8] 18.419524 20.101283 21.641728 23.052715 24.343699 25.522354 26.594991
@@ -33052,11 +33158,77 @@ NULL
 [36] 28.442320 27.566851 26.594991 25.522354 24.343699 23.052715 21.641728
 [43] 20.101283 18.419524 16.581245 14.566342 12.347138  9.883285  7.110696
 
-##com.oracle.truffle.r.test.builtins.TestBuiltin_lchoose.testlchoose3#Ignored.Unimplemented#
+##com.oracle.truffle.r.test.builtins.TestBuiltin_lchoose.testlchoose3#
 #argv <- list(0.5, 1:9); .Internal(lchoose(argv[[1]], argv[[2]]))
 [1] -0.6931472 -2.0794415 -2.7725887 -3.2425924 -3.5992673 -3.8869494 -4.1281114
 [8] -4.3357508 -4.5180723
 
+##com.oracle.truffle.r.test.builtins.TestBuiltin_lchoose.testlchoose4#
+#.Internal(lchoose(47, structure(array(21:24, dim=c(2,2)), dimnames=list(a=c('a1','a2'),b=c('b1','b2')))))
+    b
+a          b1       b2
+  a1 30.16088 30.41132
+  a2 30.32794 30.41132
+
+##com.oracle.truffle.r.test.builtins.TestBuiltin_lchoose.testlchoose4#
+#.Internal(lchoose(structure(47, myattr='hello'), 2))
+[1] 6.985642
+attr(,"myattr")
+[1] "hello"
+
+##com.oracle.truffle.r.test.builtins.TestBuiltin_lchoose.testlchoose4#
+#.Internal(lchoose(structure(array(21:24, dim=c(2,2)), dimnames=list(a=c('a1','a2'),b=c('b1','b2'))), 2))
+    b
+a          b1       b2
+  a1 5.347108 5.533389
+  a2 5.442418 5.620401
+
+##com.oracle.truffle.r.test.builtins.TestBuiltin_lchoose.testlchoose4#Output.IgnoreWarningMessage#
+#{ .Internal(lchoose(0:2, 2.2)) }
+[1] -Inf -Inf    0
+Warning messages:
+1: 'k' (2.20) must be integer, rounded to 2
+2: 'k' (2.20) must be integer, rounded to 2
+3: 'k' (2.20) must be integer, rounded to 2
+
+##com.oracle.truffle.r.test.builtins.TestBuiltin_lchoose.testlchoose4#
+#{ .Internal(lchoose(1, NA)) }
+[1] NA
+
+##com.oracle.truffle.r.test.builtins.TestBuiltin_lchoose.testlchoose4#
+#{ .Internal(lchoose(1, NULL)) }
+Error: non-numeric argument to mathematical function
+
+##com.oracle.truffle.r.test.builtins.TestBuiltin_lchoose.testlchoose4#Output.IgnoreWarningMessage#
+#{ .Internal(lchoose(2, 2.2)) }
+[1] 0
+Warning message:
+'k' (2.20) must be integer, rounded to 2
+
+##com.oracle.truffle.r.test.builtins.TestBuiltin_lchoose.testlchoose4#
+#{ .Internal(lchoose(NA, 1)) }
+[1] NA
+
+##com.oracle.truffle.r.test.builtins.TestBuiltin_lchoose.testlchoose4#
+#{ .Internal(lchoose(NULL, 1)) }
+Error: non-numeric argument to mathematical function
+
+##com.oracle.truffle.r.test.builtins.TestBuiltin_lchoose.testlchoose4#
+#{ .Internal(lchoose(c(2.2, 3.3), 2)) }
+[1] 0.2776317 1.3336844
+
+##com.oracle.truffle.r.test.builtins.TestBuiltin_lchoose.testlchoose4#
+#{ .Internal(lchoose(c(2.2, 3.3), c(2,3,4))) }
+[1]  0.2776317  0.4974364 -4.0398564
+
+##com.oracle.truffle.r.test.builtins.TestBuiltin_lchoose.testlchoose4#
+#{ .Internal(lchoose(c(2.2, 3.3, 4.4), c(2,3))) }
+[1] 0.2776317 0.4974364 2.0122328
+
+##com.oracle.truffle.r.test.builtins.TestBuiltin_lchoose.testlchoose4#
+#{ .Internal(lchoose(logical(0), logical(0))) }
+numeric(0)
+
 ##com.oracle.truffle.r.test.builtins.TestBuiltin_length.testLength#
 #length(as.symbol('x'))
 [1] 1
diff --git a/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/builtins/TestBuiltin_choose.java b/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/builtins/TestBuiltin_choose.java
index 41667fa74be05fe111328e39930d16512bf802e2..5f9ff94fc93c727615da0dd7c1d3deb221d7fcf3 100644
--- a/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/builtins/TestBuiltin_choose.java
+++ b/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/builtins/TestBuiltin_choose.java
@@ -31,11 +31,20 @@ public class TestBuiltin_choose extends TestBase {
     @Test
     public void testchooseWithLogical() {
         assertEval(".Internal(choose(logical(0), logical(0)))");
+        assertEval(".Internal(choose(FALSE, FALSE))");
+        assertEval(".Internal(choose(NA, 1))");
+        assertEval(".Internal(choose(1, NA))");
     }
 
     @Test
     public void testchoose4() {
         assertEval(".Internal(choose(0.5, 0:10))");
+        // Minor diff in warning msg: extra newline; number formatting
+        assertEval(Output.IgnoreWarningMessage, ".Internal(choose(2, 1.2))");
+        assertEval(Output.IgnoreWarningMessage, ".Internal(choose(0:2, 1.2))");
+        assertEval(".Internal(choose(structure(array(21:24, dim=c(2,2)), dimnames=list(a=c('a1','a2'),b=c('b1','b2'))), 2))");
+        assertEval(".Internal(choose(47, structure(array(21:24, dim=c(2,2)), dimnames=list(a=c('a1','a2'),b=c('b1','b2')))))");
+        assertEval(".Internal(choose(structure(47, myattr='hello'), 2))");
     }
 
     @Test
diff --git a/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/builtins/TestBuiltin_lbeta.java b/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/builtins/TestBuiltin_lbeta.java
index 6248c5a82e07931f8a49e858d6dbf29ed4e4ef5e..57167538c73d29785d2f97392f22117cc574272e 100644
--- a/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/builtins/TestBuiltin_lbeta.java
+++ b/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/builtins/TestBuiltin_lbeta.java
@@ -19,6 +19,19 @@ public class TestBuiltin_lbeta extends TestBase {
 
     @Test
     public void testlbeta1() {
-        assertEval(Ignored.Unimplemented, "argv <- list(FALSE, FALSE); .Internal(lbeta(argv[[1]], argv[[2]]))");
+        assertEval("{ .Internal(lbeta(NA, 1)) }");
+        assertEval("{ .Internal(lbeta(1, NA)) }");
+        assertEval("{ .Internal(lbeta(NULL, 1)) }");
+        assertEval("{ .Internal(lbeta(1, NULL)) }");
+        assertEval("{ .Internal(lbeta(FALSE, FALSE)) }");
+        assertEval("{ .Internal(lbeta(logical(0), logical(0))) }");
+        assertEval("{ .Internal(lbeta(2, 2.2)) }");
+        assertEval("{ .Internal(lbeta(0:2, 2.2)) }");
+        assertEval("{ .Internal(lbeta(c(2.2, 3.3), 2)) }");
+        assertEval("{ .Internal(lbeta(c(2.2, 3.3), c(2,3,4))) }");
+        assertEval("{ .Internal(lbeta(c(2.2, 3.3, 4.4), c(2,3))) }");
+        assertEval(".Internal(lbeta(structure(array(21:24, dim=c(2,2)), dimnames=list(a=c('a1','a2'),b=c('b1','b2'))), 2))");
+        assertEval(".Internal(lbeta(47, structure(array(21:24, dim=c(2,2)), dimnames=list(a=c('a1','a2'),b=c('b1','b2')))))");
+        assertEval(".Internal(lbeta(structure(47, myattr='hello'), 2))");
     }
 }
diff --git a/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/builtins/TestBuiltin_lchoose.java b/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/builtins/TestBuiltin_lchoose.java
index eb2c92a864f8a4d875aad02bb1008bbb1cdc913f..b0e1eaa81124d5701b197293f88196868cfc456b 100644
--- a/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/builtins/TestBuiltin_lchoose.java
+++ b/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/builtins/TestBuiltin_lchoose.java
@@ -19,19 +19,35 @@ public class TestBuiltin_lchoose extends TestBase {
 
     @Test
     public void testlchoose1() {
-        // FIXME not implemented: .Internal lchoose
-        assertEval(Ignored.Unimplemented, "argv <- list(FALSE, FALSE); .Internal(lchoose(argv[[1]], argv[[2]]))");
+        assertEval("argv <- list(FALSE, FALSE); .Internal(lchoose(argv[[1]], argv[[2]]))");
     }
 
     @Test
     public void testlchoose2() {
-        // FIXME not implemented: .Internal lchoose
-        assertEval(Ignored.Unimplemented, "argv <- list(50L, 0:48); .Internal(lchoose(argv[[1]], argv[[2]]))");
+        assertEval("argv <- list(50L, 0:48); .Internal(lchoose(argv[[1]], argv[[2]]))");
     }
 
     @Test
     public void testlchoose3() {
-        // FIXME not implemented: .Internal lchoose
-        assertEval(Ignored.Unimplemented, "argv <- list(0.5, 1:9); .Internal(lchoose(argv[[1]], argv[[2]]))");
+        assertEval("argv <- list(0.5, 1:9); .Internal(lchoose(argv[[1]], argv[[2]]))");
+    }
+
+    @Test
+    public void testlchoose4() {
+        assertEval("{ .Internal(lchoose(NA, 1)) }");
+        assertEval("{ .Internal(lchoose(1, NA)) }");
+        assertEval("{ .Internal(lchoose(NULL, 1)) }");
+        assertEval("{ .Internal(lchoose(1, NULL)) }");
+        assertEval("{ .Internal(lchoose(logical(0), logical(0))) }");
+        // Minor diff in warning msg: extra newline; number formatting
+        assertEval(Output.IgnoreWarningMessage, "{ .Internal(lchoose(2, 2.2)) }");
+        assertEval(Output.IgnoreWarningMessage, "{ .Internal(lchoose(0:2, 2.2)) }");
+
+        assertEval("{ .Internal(lchoose(c(2.2, 3.3), 2)) }");
+        assertEval("{ .Internal(lchoose(c(2.2, 3.3), c(2,3,4))) }");
+        assertEval("{ .Internal(lchoose(c(2.2, 3.3, 4.4), c(2,3))) }");
+        assertEval(".Internal(lchoose(structure(array(21:24, dim=c(2,2)), dimnames=list(a=c('a1','a2'),b=c('b1','b2'))), 2))");
+        assertEval(".Internal(lchoose(47, structure(array(21:24, dim=c(2,2)), dimnames=list(a=c('a1','a2'),b=c('b1','b2')))))");
+        assertEval(".Internal(lchoose(structure(47, myattr='hello'), 2))");
     }
 }