diff --git a/com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/methods/SubstituteDirect.java b/com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/methods/SubstituteDirect.java
index 420e634f2eec1004e63bb29298614c0ca00c9f7b..e1a2b1bac6bd9299591dc2e0b6c11c65f8a70994 100644
--- a/com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/methods/SubstituteDirect.java
+++ b/com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/methods/SubstituteDirect.java
@@ -27,19 +27,24 @@ import com.oracle.truffle.api.dsl.Cached;
 import com.oracle.truffle.api.dsl.Fallback;
 import com.oracle.truffle.api.dsl.Specialization;
 import com.oracle.truffle.r.nodes.RASTUtils;
+import static com.oracle.truffle.r.nodes.builtin.CastBuilder.Predef.instanceOf;
 import com.oracle.truffle.r.nodes.builtin.RExternalBuiltinNode;
 import com.oracle.truffle.r.nodes.builtin.RList2EnvNode;
 import com.oracle.truffle.r.runtime.RError;
+import static com.oracle.truffle.r.runtime.RError.Message.INVALID_LIST_FOR_SUBSTITUTION;
+import static com.oracle.truffle.r.runtime.RError.SHOW_CALLER;
 import com.oracle.truffle.r.runtime.RSubstitute;
 import com.oracle.truffle.r.runtime.data.RDataFactory;
 import com.oracle.truffle.r.runtime.data.RLanguage;
 import com.oracle.truffle.r.runtime.data.RList;
+import com.oracle.truffle.r.runtime.data.model.RAbstractListVector;
 import com.oracle.truffle.r.runtime.env.REnvironment;
 
 public abstract class SubstituteDirect extends RExternalBuiltinNode.Arg2 {
 
     static {
-        Casts.noCasts(SubstituteDirect.class);
+        Casts casts = new Casts(SubstituteDirect.class);
+        casts.arg(1).defaultError(SHOW_CALLER, INVALID_LIST_FOR_SUBSTITUTION).mustBe(instanceOf(RAbstractListVector.class).or(instanceOf(REnvironment.class)));
     }
 
     @Specialization
@@ -53,18 +58,40 @@ public abstract class SubstituteDirect extends RExternalBuiltinNode.Arg2 {
         }
     }
 
-    @Specialization
+    @Specialization(guards = {"list.getNames() == null || list.getNames().getLength() == 0"})
+    @TruffleBoundary
+    protected static Object substituteDirect(Object object, RList list) {
+        return substituteDirect(object, createNewEnvironment());
+    }
+
+    @Specialization(guards = {"list.getNames() != null", "list.getNames().getLength() > 0"})
     @TruffleBoundary
     protected static Object substituteDirect(Object object, RList list,
-                    @Cached("new()") RList2EnvNode list2Env) {
-        REnvironment env = RDataFactory.createNewEnv(null);
-        env.setParent(REnvironment.baseEnv());
-        list2Env.execute(list, env);
-        return substituteDirect(object, env);
+                    @Cached("createList2EnvNode()") RList2EnvNode list2Env) {
+        return substituteDirect(object, createEnvironment(list, list2Env));
     }
 
     @Fallback
     protected Object substituteDirect(@SuppressWarnings("unused") Object object, @SuppressWarnings("unused") Object env) {
         throw RError.error(this, RError.Message.INVALID_OR_UNIMPLEMENTED_ARGUMENTS);
     }
+
+    @TruffleBoundary
+    public static REnvironment createNewEnvironment() {
+        return createEnvironment(null, null);
+    }
+
+    @TruffleBoundary
+    public static REnvironment createEnvironment(RList list, RList2EnvNode list2Env) {
+        REnvironment env = RDataFactory.createNewEnv(null);
+        env.setParent(REnvironment.baseEnv());
+        if (list2Env != null) {
+            list2Env.execute(list, env);
+        }
+        return env;
+    }
+
+    protected static RList2EnvNode createList2EnvNode() {
+        return new RList2EnvNode(true);
+    }
 }
diff --git a/com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/stats/SplineFunctions.java b/com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/stats/SplineFunctions.java
index a16c52363c9303dd5989ea0ef4e50f67daefab72..d6b11cfc74a07bed8a89598ff39b90aeea27ec95 100644
--- a/com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/stats/SplineFunctions.java
+++ b/com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/stats/SplineFunctions.java
@@ -13,12 +13,22 @@ package com.oracle.truffle.r.library.stats;
 
 import com.oracle.truffle.api.CompilerDirectives.TruffleBoundary;
 import com.oracle.truffle.api.dsl.Specialization;
+import com.oracle.truffle.r.nodes.builtin.CastBuilder.Predef;
+import static com.oracle.truffle.r.nodes.builtin.CastBuilder.Predef.asIntegerVector;
+import static com.oracle.truffle.r.nodes.builtin.CastBuilder.Predef.chain;
+import static com.oracle.truffle.r.nodes.builtin.CastBuilder.Predef.constant;
+import static com.oracle.truffle.r.nodes.builtin.CastBuilder.Predef.findFirst;
+import static com.oracle.truffle.r.nodes.builtin.CastBuilder.Predef.integerValue;
+import static com.oracle.truffle.r.nodes.builtin.CastBuilder.Predef.numericValue;
 import com.oracle.truffle.r.nodes.builtin.RExternalBuiltinNode;
 import com.oracle.truffle.r.runtime.RError;
-import com.oracle.truffle.r.runtime.RInternalError;
+import static com.oracle.truffle.r.runtime.RError.Message.NA_INTRODUCED_COERCION;
+import static com.oracle.truffle.r.runtime.RError.NO_CALLER;
+import static com.oracle.truffle.r.runtime.RRuntime.INT_NA;
 import com.oracle.truffle.r.runtime.data.RDataFactory;
 import com.oracle.truffle.r.runtime.data.RDoubleVector;
 import com.oracle.truffle.r.runtime.data.RList;
+import com.oracle.truffle.r.runtime.data.RNull;
 import com.oracle.truffle.r.runtime.data.RStringVector;
 import com.oracle.truffle.r.runtime.data.model.RAbstractDoubleVector;
 import com.oracle.truffle.r.runtime.nmath.RMath;
@@ -32,12 +42,38 @@ import com.oracle.truffle.r.runtime.nmath.RMath;
 public class SplineFunctions {
 
     public abstract static class SplineCoef extends RExternalBuiltinNode.Arg3 {
+        static {
+            Casts casts = new Casts(SplineCoef.class);
+            casts.arg(0).mapNull(constant(INT_NA)).mapIf(numericValue(),
+                            chain(asIntegerVector()).with(findFirst().integerElement(INT_NA)).end(),
+                            chain(asIntegerVector()).with(findFirst().integerElement(INT_NA)).with(
+                                            Predef.shouldBe(integerValue(), NO_CALLER, NA_INTRODUCED_COERCION)).end());
+            casts.arg(1).allowMissing().asDoubleVector();
+            casts.arg(2).allowMissing().asDoubleVector();
+        }
+
+        @Specialization
+        @TruffleBoundary
+        protected Object splineCoef(int method, RAbstractDoubleVector x, RAbstractDoubleVector y) {
+            return SplineFunctions.splineCoef(method, x.materialize(), y.materialize());
+        }
 
         @Specialization
         @TruffleBoundary
-        protected Object splineCoef(Object method, RAbstractDoubleVector x, RAbstractDoubleVector y) {
-            int methodInt = castInt(castVector(method));
-            return SplineFunctions.splineCoef(methodInt, x.materialize(), y.materialize());
+        protected Object splineCoef(int method, RAbstractDoubleVector x, RNull y) {
+            return SplineFunctions.splineCoef(method, x.materialize(), RDataFactory.createDoubleVector(0));
+        }
+
+        @Specialization
+        @TruffleBoundary
+        protected Object splineCoef(int method, RNull x, RAbstractDoubleVector y) {
+            return SplineFunctions.splineCoef(method, RDataFactory.createDoubleVector(0), y.materialize());
+        }
+
+        @Specialization
+        @TruffleBoundary
+        protected Object splineCoef(int method, RNull x, RNull y) {
+            return SplineFunctions.splineCoef(method, RDataFactory.createDoubleVector(0), RDataFactory.createDoubleVector(0));
         }
     }
 
@@ -99,7 +135,9 @@ public class SplineFunctions {
 
         double[] e = new double[n];
 
-        RInternalError.guarantee(n >= 2 && y[0] == y[n - 1], "periodic spline: domain error");
+        if (n < 2 || y[0] != y[n - 1]) {
+            return;
+        }
 
         if (n == 2) {
             b[0] = 0.0;
@@ -215,7 +253,9 @@ public class SplineFunctions {
         int i;
         double t;
 
-        RInternalError.guarantee(n >= 2, "periodic spline: domain error");
+        if (n < 2) {
+            return;
+        }
 
         if (n < 3) {
             t = (y[1] - y[0]);
@@ -289,7 +329,9 @@ public class SplineFunctions {
         int i;
         double t;
 
-        RInternalError.guarantee(n >= 2, "periodic spline: domain error");
+        if (n < 2) {
+            return;
+        }
 
         if (n < 3) {
             t = (y[1] - y[0]);
diff --git a/com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/utils/TypeConvert.java b/com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/utils/TypeConvert.java
index fb7fbf6c6a7507970d79da42414cb223c82c6fc9..27d158bbc8bae512d152b6ea83ef2e9a44258e5f 100644
--- a/com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/utils/TypeConvert.java
+++ b/com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/utils/TypeConvert.java
@@ -27,8 +27,20 @@ import java.util.TreeSet;
 
 import com.oracle.truffle.api.dsl.Specialization;
 import com.oracle.truffle.r.nodes.attributes.SetFixedAttributeNode;
+import static com.oracle.truffle.r.nodes.builtin.CastBuilder.Predef.asLogicalVector;
+import static com.oracle.truffle.r.nodes.builtin.CastBuilder.Predef.chain;
+import static com.oracle.truffle.r.nodes.builtin.CastBuilder.Predef.constant;
+import static com.oracle.truffle.r.nodes.builtin.CastBuilder.Predef.findFirst;
+import static com.oracle.truffle.r.nodes.builtin.CastBuilder.Predef.logicalValue;
+import static com.oracle.truffle.r.nodes.builtin.CastBuilder.Predef.map;
+import static com.oracle.truffle.r.nodes.builtin.CastBuilder.Predef.stringValue;
+import static com.oracle.truffle.r.nodes.builtin.CastBuilder.Predef.toBoolean;
 import com.oracle.truffle.r.nodes.builtin.RExternalBuiltinNode;
+import static com.oracle.truffle.r.runtime.RError.Message.FIRST_ARGUMENT_MUST_BE_CHARACTER;
+import static com.oracle.truffle.r.runtime.RError.Message.INVALID_ARG;
+import static com.oracle.truffle.r.runtime.RError.SHOW_CALLER;
 import com.oracle.truffle.r.runtime.RRuntime;
+import static com.oracle.truffle.r.runtime.RRuntime.LOGICAL_FALSE;
 import com.oracle.truffle.r.runtime.data.RDataFactory;
 import com.oracle.truffle.r.runtime.data.RDoubleVector;
 import com.oracle.truffle.r.runtime.data.RIntVector;
@@ -41,7 +53,12 @@ public abstract class TypeConvert extends RExternalBuiltinNode.Arg5 {
     @Child private SetFixedAttributeNode setLevelsAttrNode = SetFixedAttributeNode.create(RRuntime.LEVELS_ATTR_KEY);
 
     static {
-        Casts.noCasts(TypeConvert.class);
+        Casts casts = new Casts(TypeConvert.class);
+        casts.arg(0).mustBe(stringValue(), SHOW_CALLER, FIRST_ARGUMENT_MUST_BE_CHARACTER).asStringVector();
+        casts.arg(1).mustBe(stringValue(), SHOW_CALLER, INVALID_ARG, "'na.strings'").asStringVector();
+        casts.arg(2).mapIf(logicalValue(),
+                        chain(asLogicalVector()).with(findFirst().logicalElement(LOGICAL_FALSE)).with(toBoolean()).end(),
+                        chain(map(constant(LOGICAL_FALSE))).with(toBoolean()).end());
     }
 
     private static boolean isNA(String s, RAbstractStringVector naStrings) {
@@ -109,7 +126,7 @@ public abstract class TypeConvert extends RExternalBuiltinNode.Arg5 {
     }
 
     @Specialization
-    protected Object typeConvert(RAbstractStringVector x, RAbstractStringVector naStrings, byte asIs, @SuppressWarnings("unused") Object dec, @SuppressWarnings("unused") Object numeral) {
+    protected Object typeConvert(RAbstractStringVector x, RAbstractStringVector naStrings, boolean asIs, @SuppressWarnings("unused") Object dec, @SuppressWarnings("unused") Object numeral) {
         if (x.getLength() == 0) {
             return RDataFactory.createEmptyLogicalVector();
         }
@@ -164,7 +181,7 @@ public abstract class TypeConvert extends RExternalBuiltinNode.Arg5 {
         }
         // fall through target - conversion to int, double or logical failed
 
-        if (asIs == RRuntime.LOGICAL_TRUE) {
+        if (asIs) {
             return x;
         } else {
             // create a factor
diff --git a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/Substitute.java b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/Substitute.java
index 395271e222dbd22d65793354e36b294d7a923ae5..8f75d3805283f2630e15b5072874c9e3b4d7c5fe 100644
--- a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/Substitute.java
+++ b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/Substitute.java
@@ -26,20 +26,25 @@ import static com.oracle.truffle.r.runtime.builtins.RBehavior.COMPLEX;
 import static com.oracle.truffle.r.runtime.builtins.RBuiltinKind.PRIMITIVE;
 
 import com.oracle.truffle.api.CompilerDirectives;
-import com.oracle.truffle.api.dsl.Fallback;
+import com.oracle.truffle.api.dsl.Cached;
 import com.oracle.truffle.api.dsl.Specialization;
 import com.oracle.truffle.api.frame.VirtualFrame;
+import com.oracle.truffle.r.library.methods.SubstituteDirect;
 import com.oracle.truffle.r.nodes.RASTUtils;
+import static com.oracle.truffle.r.nodes.builtin.CastBuilder.Predef.instanceOf;
 import com.oracle.truffle.r.nodes.builtin.RBuiltinNode;
+import com.oracle.truffle.r.nodes.builtin.RList2EnvNode;
 import com.oracle.truffle.r.nodes.control.IfNode;
-import com.oracle.truffle.r.runtime.RError;
+import static com.oracle.truffle.r.runtime.RError.Message.INVALID_ENVIRONMENT_SPECIFIED;
 import com.oracle.truffle.r.runtime.RSubstitute;
 import com.oracle.truffle.r.runtime.builtins.RBuiltin;
 import com.oracle.truffle.r.runtime.data.RLanguage;
 import com.oracle.truffle.r.runtime.data.RList;
 import com.oracle.truffle.r.runtime.data.RMissing;
+import com.oracle.truffle.r.runtime.data.RNull;
 import com.oracle.truffle.r.runtime.data.RPromise;
 import com.oracle.truffle.r.runtime.data.RSymbol;
+import com.oracle.truffle.r.runtime.data.model.RAbstractListVector;
 import com.oracle.truffle.r.runtime.env.REnvironment;
 
 @RBuiltin(name = "substitute", kind = PRIMITIVE, parameterNames = {"expr", "env"}, nonEvalArgs = 0, behavior = COMPLEX)
@@ -48,7 +53,8 @@ public abstract class Substitute extends RBuiltinNode {
     @Child private Quote quote;
 
     static {
-        Casts.noCasts(Substitute.class);
+        Casts casts = new Casts(Substitute.class);
+        casts.arg(1).allowNullAndMissing().defaultError(INVALID_ENVIRONMENT_SPECIFIED).mustBe(instanceOf(RAbstractListVector.class).or(instanceOf(REnvironment.class)));
     }
 
     @Specialization
@@ -56,19 +62,25 @@ public abstract class Substitute extends RBuiltinNode {
         return doSubstituteWithEnv(expr, REnvironment.frameToEnvironment(frame.materialize()));
     }
 
+    @Specialization
+    protected Object doSubstitute(VirtualFrame frame, RPromise expr, @SuppressWarnings("unused") RNull env) {
+        return doSubstituteWithEnv(expr, REnvironment.frameToEnvironment(frame.materialize()));
+    }
+
     @Specialization
     protected Object doSubstitute(RPromise expr, REnvironment env) {
         return doSubstituteWithEnv(expr, env);
     }
 
-    @Specialization
+    @Specialization(guards = {"list.getNames() == null || list.getNames().getLength() == 0"})
     protected Object doSubstitute(RPromise expr, RList list) {
-        return doSubstituteWithEnv(expr, REnvironment.createFromList(list, REnvironment.baseEnv()));
+        return doSubstituteWithEnv(expr, SubstituteDirect.createNewEnvironment());
     }
 
-    @Fallback
-    protected Object doSubstitute(@SuppressWarnings("unused") Object expr, @SuppressWarnings("unused") Object x) {
-        throw RError.error(this, RError.Message.INVALID_ENVIRONMENT);
+    @Specialization(guards = {"list.getNames() != null", "list.getNames().getLength() > 0"})
+    protected Object doSubstitute(RPromise expr, RList list,
+                    @Cached("createList2EnvNode()") RList2EnvNode list2Env) {
+        return doSubstituteWithEnv(expr, SubstituteDirect.createEnvironment(list, list2Env));
     }
 
     /**
@@ -99,4 +111,9 @@ public abstract class Substitute extends RBuiltinNode {
         // so get the actual expression (AST) from that
         return RASTUtils.createLanguageElement(RSubstitute.substitute(env, expr.getRep()));
     }
+
+    protected static RList2EnvNode createList2EnvNode() {
+        return new RList2EnvNode(true);
+    }
+
 }
diff --git a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/foreign/Dqrcf.java b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/foreign/Dqrcf.java
index 6941258c6b612ed2902233fbe2d980d23a68585d..d10efffa16e25c225bdecc3541acd60262ca89f1 100644
--- a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/foreign/Dqrcf.java
+++ b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/foreign/Dqrcf.java
@@ -11,10 +11,12 @@
  */
 package com.oracle.truffle.r.nodes.builtin.base.foreign;
 
+import com.oracle.truffle.api.dsl.Specialization;
+import static com.oracle.truffle.r.nodes.builtin.CastBuilder.Predef.doubleValue;
+import static com.oracle.truffle.r.nodes.builtin.CastBuilder.Predef.integerValue;
 import com.oracle.truffle.r.nodes.builtin.RExternalBuiltinNode;
 import com.oracle.truffle.r.runtime.RError;
 import com.oracle.truffle.r.runtime.RRuntime;
-import com.oracle.truffle.r.runtime.data.RArgsValuesAndNames;
 import com.oracle.truffle.r.runtime.data.RDataFactory;
 import com.oracle.truffle.r.runtime.data.RDoubleVector;
 import com.oracle.truffle.r.runtime.data.RList;
@@ -24,44 +26,43 @@ import com.oracle.truffle.r.runtime.data.model.RAbstractIntVector;
 import com.oracle.truffle.r.runtime.ffi.RApplRFFI;
 import com.oracle.truffle.r.runtime.ffi.RFFIFactory;
 
-public final class Dqrcf extends RExternalBuiltinNode {
+public abstract class Dqrcf extends RExternalBuiltinNode.Arg8 {
     @Child private RApplRFFI.RApplRFFINode rApplRFFINode = RFFIFactory.getRFFI().getRApplRFFI().createRApplRFFINode();
 
     private static final String E = RRuntime.NAMES_ATTR_EMPTY_VALUE;
     private static final RStringVector DQRCF_NAMES = RDataFactory.createStringVector(new String[]{E, E, E, E, E, E, "coef", "info"}, RDataFactory.COMPLETE_VECTOR);
 
     static {
-        Casts.noCasts(Dqrcf.class);
+        Casts casts = new Casts(Dqrcf.class);
+        casts.arg(0).mustBe(doubleValue()).asDoubleVector();
+        casts.arg(1).mustBe(integerValue()).asIntegerVector().findFirst();
+        casts.arg(2).mustBe(integerValue()).asIntegerVector().findFirst();
+        casts.arg(3).mustBe(doubleValue()).asDoubleVector();
+        casts.arg(4).mustBe(doubleValue()).asDoubleVector();
+        casts.arg(5).mustBe(integerValue()).asIntegerVector().findFirst();
+        casts.arg(6).mustBe(doubleValue()).asDoubleVector();
+        casts.arg(7).mustBe(integerValue()).asIntegerVector();
     }
 
-    @Override
-    public RList call(RArgsValuesAndNames args) {
-        Object[] argValues = args.getArguments();
+    @Specialization
+    public RList dqrcf(RAbstractDoubleVector xVec, int nx, int k, RAbstractDoubleVector qrauxVec, RAbstractDoubleVector yVec, int ny, RAbstractDoubleVector bVec, RAbstractIntVector infoVec) {
         try {
-            RAbstractDoubleVector xVec = (RAbstractDoubleVector) argValues[0];
-            int n = argValues[1] instanceof Integer ? (int) argValues[1] : ((RAbstractIntVector) argValues[1]).getDataAt(0);
-            RAbstractIntVector k = (RAbstractIntVector) argValues[2];
-            RAbstractDoubleVector qrauxVec = (RAbstractDoubleVector) argValues[3];
-            RAbstractDoubleVector yVec = (RAbstractDoubleVector) argValues[4];
-            int ny = argValues[5] instanceof Integer ? (int) argValues[5] : ((RAbstractIntVector) argValues[5]).getDataAt(0);
-            RAbstractDoubleVector bVec = (RAbstractDoubleVector) argValues[6];
-            RAbstractIntVector infoVec = (RAbstractIntVector) argValues[7];
             double[] x = xVec.materialize().getDataTemp();
             double[] qraux = qrauxVec.materialize().getDataTemp();
             double[] y = yVec.materialize().getDataTemp();
             double[] b = bVec.materialize().getDataTemp();
             int[] info = infoVec.materialize().getDataTemp();
-            rApplRFFINode.dqrcf(x, n, k.getDataAt(0), qraux, y, ny, b, info);
+            rApplRFFINode.dqrcf(x, nx, k, qraux, y, ny, b, info);
             RDoubleVector coef = RDataFactory.createDoubleVector(b, RDataFactory.COMPLETE_VECTOR);
             coef.copyAttributesFrom(bVec);
             // @formatter:off
             Object[] data = new Object[]{
                         RDataFactory.createDoubleVector(x, RDataFactory.COMPLETE_VECTOR),
-                        argValues[1],
-                        k.copy(),
+                        nx,
+                        k,
                         RDataFactory.createDoubleVector(qraux, RDataFactory.COMPLETE_VECTOR),
                         RDataFactory.createDoubleVector(y, RDataFactory.COMPLETE_VECTOR),
-                        argValues[5],
+                        ny,
                         coef,
                         RDataFactory.createIntVector(info, RDataFactory.COMPLETE_VECTOR),
             };
diff --git a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/foreign/FortranAndCFunctions.java b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/foreign/FortranAndCFunctions.java
index 29a1c389bc5f02ccb1e0f7f6f6d6e6a8d7dc86ea..d3d6625fa2359679f28b4d1dc87917ff036161e7 100644
--- a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/foreign/FortranAndCFunctions.java
+++ b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/foreign/FortranAndCFunctions.java
@@ -203,7 +203,7 @@ public class FortranAndCFunctions {
                 case "dqrdc2":
                     return Dqrdc2.create();
                 case "dqrcf":
-                    return new Dqrcf();
+                    return DqrcfNodeGen.create();
                 default:
                     return null;
             }
diff --git a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/builtin/RList2EnvNode.java b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/builtin/RList2EnvNode.java
index a50458a51a216058dcab72e3f6c6ef9989e731b0..cc2264b97ca612c1b46b448bac53deb1b6c53991 100644
--- a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/builtin/RList2EnvNode.java
+++ b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/builtin/RList2EnvNode.java
@@ -33,6 +33,15 @@ import com.oracle.truffle.r.runtime.nodes.RBaseNode;
  * Abstracted for use by other nodes that need to convert a list into an environment.
  */
 public final class RList2EnvNode extends RBaseNode {
+    private final boolean ignoreMissingNames;
+
+    public RList2EnvNode() {
+        this(false);
+    }
+
+    public RList2EnvNode(boolean ignoreMissingNames) {
+        this.ignoreMissingNames = ignoreMissingNames;
+    }
 
     @TruffleBoundary
     public REnvironment execute(RAbstractListVector list, REnvironment env) {
@@ -45,7 +54,7 @@ public final class RList2EnvNode extends RBaseNode {
         }
         for (int i = list.getLength() - 1; i >= 0; i--) {
             String name = names.getDataAt(i);
-            if (name.length() == 0) {
+            if (!ignoreMissingNames && name.length() == 0) {
                 throw RError.error(this, RError.Message.ZERO_LENGTH_VARIABLE);
             }
             // in case of duplicates, last element in list wins
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 9f4d41c7fecbc2e3a4727e166884132a884d4baf..58bc36b5d7dca83785af1de7a2e8441c12996c05 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
@@ -409,6 +409,7 @@ public final class RError extends RuntimeException {
         PROMISE_CYCLE("promise already under evaluation: recursive default argument reference or earlier problems?"),
         MISSING_ARGUMENTS("'missing' can only be used for arguments"),
         INVALID_ENVIRONMENT("invalid environment"),
+        INVALID_ENVIRONMENT_SPECIFIED("invalid environment specified"),
         ENVIR_NOT_LENGTH_ONE("numeric 'envir' arg not of length one"),
         FMT_NOT_CHARACTER("'fmt' is not a character vector"),
         UNSUPPORTED_TYPE("unsupported type"),
@@ -559,6 +560,7 @@ public final class RError extends RuntimeException {
         INVALID_LOGICAL("'%s' must be TRUE or FALSE"),
         INVALID_FORMAT_STRING("invalid format '%s'; use format %%s for character objects"),
         MUST_BE_CHARACTER("'%s' must be of mode character"),
+        FIRST_ARGUMENT_MUST_BE_CHARACTER("the first argument must be of mode character"),
         ALL_ATTRIBUTES_NAMES("all attributes must have names [%d does not]"),
         INVALID_REGEXP("invalid regular expression '%s'"),
         COERCING_ARGUMENT("coercing argument of type '%s' to %s"),
@@ -598,6 +600,7 @@ public final class RError extends RuntimeException {
         NOT_A_SYMBOL("not a symbol"),
         CANNOT_SET_PARENT("cannot set the parent of the empty environment"),
         INVALID_OR_UNIMPLEMENTED_ARGUMENTS("invalid or unimplemented arguments"),
+        INVALID_LIST_FOR_SUBSTITUTION("invalid list for substitution"),
         NOTHING_TO_LINK("nothing to link"),
         FROM_TO_DIFFERENT("'from' and 'to' are of different lengths"),
         NA_IN_FOREIGN_FUNCTION_CALL("NAs in foreign function call (arg %d)"),
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 14957271ae4861476e601f32f157aa17b1e65741..a3561e1ed91a693aa25ce508c92a7f4fb8704cc3 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
@@ -63063,6 +63063,54 @@ Warning message:
 In `[.data.frame`(x = list(Satellites = c(8L, 0L, 9L, 0L, 4L, 0L,  :
   named arguments other than 'drop' are discouraged
 
+##com.oracle.truffle.r.test.builtins.TestBuiltin_substitute.testSubstitute#
+#a<-substitute(quote(x+1), NA); a
+Error in substitute(quote(x + 1), NA) : invalid environment specified
+
+##com.oracle.truffle.r.test.builtins.TestBuiltin_substitute.testSubstitute#
+#a<-substitute(quote(x+1), NULL); a
+quote(x + 1)
+
+##com.oracle.truffle.r.test.builtins.TestBuiltin_substitute.testSubstitute#
+#a<-substitute(quote(x+1), c(c(list(x=1)))); a
+quote(1 + 1)
+
+##com.oracle.truffle.r.test.builtins.TestBuiltin_substitute.testSubstitute#
+#a<-substitute(quote(x+1), c(list(x=1), 'breakme')); a
+quote(1 + 1)
+
+##com.oracle.truffle.r.test.builtins.TestBuiltin_substitute.testSubstitute#
+#a<-substitute(quote(x+1), c(list(x=1, 1))); a
+quote(1 + 1)
+
+##com.oracle.truffle.r.test.builtins.TestBuiltin_substitute.testSubstitute#
+#a<-substitute(quote(x+1), list(1)); a
+quote(x + 1)
+
+##com.oracle.truffle.r.test.builtins.TestBuiltin_substitute.testSubstitute#
+#a<-substitute(quote(x+1), list(c(c(list(x=1))))); a
+quote(x + 1)
+
+##com.oracle.truffle.r.test.builtins.TestBuiltin_substitute.testSubstitute#
+#a<-substitute(quote(x+1), list(list(x=1))); a
+quote(x + 1)
+
+##com.oracle.truffle.r.test.builtins.TestBuiltin_substitute.testSubstitute#
+#a<-substitute(quote(x+1), list(x=1)); a
+quote(1 + 1)
+
+##com.oracle.truffle.r.test.builtins.TestBuiltin_substitute.testSubstitute#
+#a<-substitute(quote(x+1), list(y=1)); a
+quote(x + 1)
+
+##com.oracle.truffle.r.test.builtins.TestBuiltin_substitute.testSubstitute#
+#a<-substitute(quote(x+y), c(list(x=1), list(y=1))); a
+quote(1 + 1)
+
+##com.oracle.truffle.r.test.builtins.TestBuiltin_substitute.testSubstitute#
+#f<-function() {}; substitute(quote(x+1), f)
+Error in substitute(quote(x + 1), f) : invalid environment specified
+
 ##com.oracle.truffle.r.test.builtins.TestBuiltin_substitute.testSubstitute#
 #f<-function(...) { print(typeof(get('...'))); environment() }; e <- f(c(1,2), b=15, c=44); substitute(foo2({...}), e)
 [1] "..."
@@ -63112,6 +63160,47 @@ foo@bar
 #f<-function(x,name) substitute(x@name<-2); f(foo, bar)
 foo@bar <- 2
 
+##com.oracle.truffle.r.test.builtins.TestBuiltin_substitute.testSubstitute#
+#substitute(1, 1)
+Error in substitute(1, 1) : invalid environment specified
+
+##com.oracle.truffle.r.test.builtins.TestBuiltin_substitute.testSubstitute#
+#substitute(1, 1, 1)
+Error in substitute(1, 1, 1) : unused argument (1)
+
+##com.oracle.truffle.r.test.builtins.TestBuiltin_substitute.testSubstitute#
+#substitute(1, NA)
+Error in substitute(1, NA) : invalid environment specified
+
+##com.oracle.truffle.r.test.builtins.TestBuiltin_substitute.testSubstitute#
+#substitute(1, NULL)
+[1] 1
+
+##com.oracle.truffle.r.test.builtins.TestBuiltin_substitute.testSubstitute#
+#substitute(1, c(list(1)))
+[1] 1
+
+##com.oracle.truffle.r.test.builtins.TestBuiltin_substitute.testSubstitute#
+#substitute(1, list(c(list(1))))
+[1] 1
+
+##com.oracle.truffle.r.test.builtins.TestBuiltin_substitute.testSubstitute#
+#substitute(1, list(list(1)))
+[1] 1
+
+##com.oracle.truffle.r.test.builtins.TestBuiltin_substitute.testSubstitute#
+#substitute(expr=1, env=1)
+Error in substitute(expr = 1, env = 1) : invalid environment specified
+
+##com.oracle.truffle.r.test.builtins.TestBuiltin_substitute.testSubstitute#
+#substitute(quote(x+1), environment())
+quote(x + 1)
+
+##com.oracle.truffle.r.test.builtins.TestBuiltin_substitute.testSubstitute#
+#substitute(quote(x+1), setClass('a'))
+Error in substitute(quote(x + 1), setClass("a")) :
+  invalid environment specified
+
 ##com.oracle.truffle.r.test.builtins.TestBuiltin_substitute.testSubstitute#
 #{ delayedAssign("expr", a * b) ; substitute(expr) }
 expr
@@ -125414,6 +125503,168 @@ attr(,"is.truffle.object")
 #{ library(grid); unit.c(unit(1,'mm'), unit(1,'mm')) }
 [1] 1mm 1mm
 
+##com.oracle.truffle.r.test.library.methods.TestSubstituteDirect.basicTests#
+#a<-substituteDirect(quote(x+1), NA); a
+Error in substituteDirect(quote(x + 1), NA) :
+  invalid list for substitution
+
+##com.oracle.truffle.r.test.library.methods.TestSubstituteDirect.basicTests#
+#a<-substituteDirect(quote(x+1), NULL); a
+Error in substituteDirect(quote(x + 1), NULL) :
+  invalid list for substitution
+
+##com.oracle.truffle.r.test.library.methods.TestSubstituteDirect.basicTests#
+#a<-substituteDirect(quote(x+1), c(c(list(x=1)))); a
+1 + 1
+
+##com.oracle.truffle.r.test.library.methods.TestSubstituteDirect.basicTests#
+#a<-substituteDirect(quote(x+1), c(list(x=1), 'breakme')); a
+1 + 1
+
+##com.oracle.truffle.r.test.library.methods.TestSubstituteDirect.basicTests#
+#a<-substituteDirect(quote(x+1), c(list(x=1, 1))); a
+1 + 1
+
+##com.oracle.truffle.r.test.library.methods.TestSubstituteDirect.basicTests#
+#a<-substituteDirect(quote(x+1), list(1)); a
+x + 1
+
+##com.oracle.truffle.r.test.library.methods.TestSubstituteDirect.basicTests#
+#a<-substituteDirect(quote(x+1), list(c(c(list(x=1))))); a
+x + 1
+
+##com.oracle.truffle.r.test.library.methods.TestSubstituteDirect.basicTests#
+#a<-substituteDirect(quote(x+1), list(list(x=1))); a
+x + 1
+
+##com.oracle.truffle.r.test.library.methods.TestSubstituteDirect.basicTests#
+#a<-substituteDirect(quote(x+1), list(x=1)); a
+1 + 1
+
+##com.oracle.truffle.r.test.library.methods.TestSubstituteDirect.basicTests#
+#a<-substituteDirect(quote(x+1), list(y=1)); a
+x + 1
+
+##com.oracle.truffle.r.test.library.methods.TestSubstituteDirect.basicTests#
+#a<-substituteDirect(quote(x+y), c(list(x=1), list(y=1))); a
+1 + 1
+
+##com.oracle.truffle.r.test.library.methods.TestSubstituteDirect.basicTests#
+#f<-function() {}; substituteDirect(quote(x+1), frame=f)
+Error in substituteDirect(quote(x + 1), frame = f) :
+  invalid list for substitution
+
+##com.oracle.truffle.r.test.library.methods.TestSubstituteDirect.basicTests#
+#substituteDirect(1, 1)
+Error in substituteDirect(1, 1) : invalid list for substitution
+
+##com.oracle.truffle.r.test.library.methods.TestSubstituteDirect.basicTests#
+#substituteDirect(1, 1, 1)
+Error in substituteDirect(1, 1, 1) : invalid list for substitution
+
+##com.oracle.truffle.r.test.library.methods.TestSubstituteDirect.basicTests#
+#substituteDirect(1, frame=NA)
+Error in substituteDirect(1, frame = NA) : invalid list for substitution
+
+##com.oracle.truffle.r.test.library.methods.TestSubstituteDirect.basicTests#
+#substituteDirect(1, frame=NULL)
+Error in substituteDirect(1, frame = NULL) :
+  invalid list for substitution
+
+##com.oracle.truffle.r.test.library.methods.TestSubstituteDirect.basicTests#
+#substituteDirect(NA, list(x=1))
+[1] NA
+
+##com.oracle.truffle.r.test.library.methods.TestSubstituteDirect.basicTests#
+#substituteDirect(NULL, list(x=1))
+NULL
+
+##com.oracle.truffle.r.test.library.methods.TestSubstituteDirect.basicTests#
+#substituteDirect(environment(), list(x=1))
+<environment: R_GlobalEnv>
+
+##com.oracle.truffle.r.test.library.methods.TestSubstituteDirect.basicTests#
+#substituteDirect(object=1, frame=1)
+Error in substituteDirect(object = 1, frame = 1) :
+  invalid list for substitution
+
+##com.oracle.truffle.r.test.library.methods.TestSubstituteDirect.basicTests#
+#substituteDirect(object=1, frame=1, cleanFunction=1)
+Error in substituteDirect(object = 1, frame = 1, cleanFunction = 1) :
+  invalid list for substitution
+
+##com.oracle.truffle.r.test.library.methods.TestSubstituteDirect.basicTests#
+#substituteDirect(object=1, frame=c(list(1)))
+[1] 1
+
+##com.oracle.truffle.r.test.library.methods.TestSubstituteDirect.basicTests#
+#substituteDirect(object=1, frame=list(c(list(1))))
+[1] 1
+
+##com.oracle.truffle.r.test.library.methods.TestSubstituteDirect.basicTests#
+#substituteDirect(object=1, frame=list(list(1)))
+[1] 1
+
+##com.oracle.truffle.r.test.library.methods.TestSubstituteDirect.basicTests#
+#substituteDirect(quote(x+1), frame=environment())
+x + 1
+
+##com.oracle.truffle.r.test.library.methods.TestSubstituteDirect.basicTests#
+#substituteDirect(quote(x+1), frame=setClass('a'))
+Error in substituteDirect(quote(x + 1), frame = setClass("a")) :
+  invalid list for substitution
+
+##com.oracle.truffle.r.test.library.methods.TestSubstituteDirect.basicTests#
+#substituteDirect(quote(x+1), list(x=1), cleanFunction='a')
+Error in cleanFunction && is.function(value) :
+  invalid 'x' type in 'x && y'
+
+##com.oracle.truffle.r.test.library.methods.TestSubstituteDirect.basicTests#
+#substituteDirect(quote(x+1), list(x=1), cleanFunction=NA)
+1 + 1
+
+##com.oracle.truffle.r.test.library.methods.TestSubstituteDirect.basicTests#
+#substituteDirect(quote(x+1), list(x=1), cleanFunction=NULL)
+Error in cleanFunction && is.function(value) :
+  invalid 'x' type in 'x && y'
+
+##com.oracle.truffle.r.test.library.methods.TestSubstituteDirect.basicTests#
+#substituteDirect(quote(x+1), list(x=1), cleanFunction=TRUE)
+1 + 1
+
+##com.oracle.truffle.r.test.library.methods.TestSubstituteDirect.basicTests#
+#substituteDirect(quote(x+1), list(x=1), cleanFunction=c('1'))
+Error in cleanFunction && is.function(value) :
+  invalid 'x' type in 'x && y'
+
+##com.oracle.truffle.r.test.library.methods.TestSubstituteDirect.basicTests#
+#substituteDirect(quote(x+1), list(x=1), cleanFunction=c(1))
+1 + 1
+
+##com.oracle.truffle.r.test.library.methods.TestSubstituteDirect.basicTests#
+#substituteDirect(quote(x+1), list(x=1), cleanFunction=c(TRUE, 'breakme'))
+Error in cleanFunction && is.function(value) :
+  invalid 'x' type in 'x && y'
+
+##com.oracle.truffle.r.test.library.methods.TestSubstituteDirect.basicTests#
+#substituteDirect(quote(x+1), list(x=1), cleanFunction=c(TRUE, FALSE))
+1 + 1
+
+##com.oracle.truffle.r.test.library.methods.TestSubstituteDirect.basicTests#
+#substituteDirect(quote(x+1), list(x=1), cleanFunction=c(c(TRUE, 'breakme')))
+Error in cleanFunction && is.function(value) :
+  invalid 'x' type in 'x && y'
+
+##com.oracle.truffle.r.test.library.methods.TestSubstituteDirect.basicTests#
+#substituteDirect(quote(x+1), list(x=1), cleanFunction=environment())
+Error in cleanFunction && is.function(value) :
+  invalid 'x' type in 'x && y'
+
+##com.oracle.truffle.r.test.library.methods.TestSubstituteDirect.basicTests#
+#substituteDirect(quote(x+1), list(x=1), cleanFunction=list(c(TRUE), 'breakme'))
+Error in cleanFunction && is.function(value) :
+  invalid 'x' type in 'x && y'
+
 ##com.oracle.truffle.r.test.library.stats.TestDistributions.testDensityFunctions#Output.MayIgnoreWarningContext#
 #dbeta(0, -1,  0.5)
 [1] NaN
@@ -134587,6 +134838,651 @@ B    5    8    4    7    6    2    6
 [2,]    2    0    0    1    0
 [3,]    1    2    3    2    3
 
+##com.oracle.truffle.r.test.library.stats.TestSplineFunctions.basicSplineCoef#Ignored.WrongCaller#
+#.Call(stats:::C_SplineCoef, 'abc', c(1:5), c(1:5))
+$method
+[1] NA
+
+$n
+[1] 5
+
+$x
+[1] 1 2 3 4 5
+
+$y
+[1] 1 2 3 4 5
+
+$b
+[1] 0 0 0 0 0
+
+$c
+[1] 0 0 0 0 0
+
+$d
+[1] 0 0 0 0 0
+
+Warning message:
+NAs introduced by coercion
+
+##com.oracle.truffle.r.test.library.stats.TestSplineFunctions.basicSplineCoef#
+#.Call(stats:::C_SplineCoef, -1, c(1:5), c(1:5))
+$method
+[1] -1
+
+$n
+[1] 5
+
+$x
+[1] 1 2 3 4 5
+
+$y
+[1] 1 2 3 4 5
+
+$b
+[1] 0 0 0 0 0
+
+$c
+[1] 0 0 0 0 0
+
+$d
+[1] 0 0 0 0 0
+
+
+##com.oracle.truffle.r.test.library.stats.TestSplineFunctions.basicSplineCoef#
+#.Call(stats:::C_SplineCoef, 0, c(1:5), c(1:5))
+$method
+[1] 0
+
+$n
+[1] 5
+
+$x
+[1] 1 2 3 4 5
+
+$y
+[1] 1 2 3 4 5
+
+$b
+[1] 0 0 0 0 0
+
+$c
+[1] 0 0 0 0 0
+
+$d
+[1] 0 0 0 0 0
+
+
+##com.oracle.truffle.r.test.library.stats.TestSplineFunctions.basicSplineCoef#
+#.Call(stats:::C_SplineCoef, 1, NA, NA)
+$method
+[1] 1
+
+$n
+[1] 1
+
+$x
+[1] NA
+
+$y
+[1] NA
+
+$b
+[1] 0
+
+$c
+[1] 0
+
+$d
+[1] 0
+
+
+##com.oracle.truffle.r.test.library.stats.TestSplineFunctions.basicSplineCoef#
+#.Call(stats:::C_SplineCoef, 1, NA, c(1:5))
+Error: inputs of different lengths
+
+##com.oracle.truffle.r.test.library.stats.TestSplineFunctions.basicSplineCoef#
+#.Call(stats:::C_SplineCoef, 1, NULL, NULL)
+$method
+[1] 1
+
+$n
+[1] 0
+
+$x
+numeric(0)
+
+$y
+numeric(0)
+
+$b
+numeric(0)
+
+$c
+numeric(0)
+
+$d
+numeric(0)
+
+
+##com.oracle.truffle.r.test.library.stats.TestSplineFunctions.basicSplineCoef#
+#.Call(stats:::C_SplineCoef, 1, NULL, c(1:5))
+Error: inputs of different lengths
+
+##com.oracle.truffle.r.test.library.stats.TestSplineFunctions.basicSplineCoef#
+#.Call(stats:::C_SplineCoef, 1, c(1), c(1))
+$method
+[1] 1
+
+$n
+[1] 1
+
+$x
+[1] 1
+
+$y
+[1] 1
+
+$b
+[1] 0
+
+$c
+[1] 0
+
+$d
+[1] 0
+
+
+##com.oracle.truffle.r.test.library.stats.TestSplineFunctions.basicSplineCoef#
+#.Call(stats:::C_SplineCoef, 1, c(1), list(1))
+$method
+[1] 1
+
+$n
+[1] 1
+
+$x
+[1] 1
+
+$y
+[1] 1
+
+$b
+[1] 0
+
+$c
+[1] 0
+
+$d
+[1] 0
+
+
+##com.oracle.truffle.r.test.library.stats.TestSplineFunctions.basicSplineCoef#
+#.Call(stats:::C_SplineCoef, 1, c(1:5), NA)
+Error: inputs of different lengths
+
+##com.oracle.truffle.r.test.library.stats.TestSplineFunctions.basicSplineCoef#
+#.Call(stats:::C_SplineCoef, 1, c(1:5), NULL)
+Error: inputs of different lengths
+
+##com.oracle.truffle.r.test.library.stats.TestSplineFunctions.basicSplineCoef#
+#.Call(stats:::C_SplineCoef, 1, c(1:5), c(1:5))
+$method
+[1] 1
+
+$n
+[1] 5
+
+$x
+[1] 1 2 3 4 5
+
+$y
+[1] 1 2 3 4 5
+
+$b
+[1] 0 0 0 0 0
+
+$c
+[1] 0 0 0 0 0
+
+$d
+[1] 0 0 0 0 0
+
+
+##com.oracle.truffle.r.test.library.stats.TestSplineFunctions.basicSplineCoef#
+#.Call(stats:::C_SplineCoef, 1, c(1:6), c(1:5, 1))
+$method
+[1] 1
+
+$n
+[1] 6
+
+$x
+[1] 1 2 3 4 5 6
+
+$y
+[1] 1 2 3 4 5 1
+
+$b
+[1] -2.1818182  1.9090909  0.5454545  1.9090909 -2.1818182 -2.1818182
+
+$c
+[1]  5.454545e+00 -1.363636e+00 -2.154731e-17  1.363636e+00 -5.454545e+00
+[6]  5.454545e+00
+
+$d
+[1] -2.2727273  0.4545455  0.4545455 -2.2727273  3.6363636 -2.2727273
+
+
+##com.oracle.truffle.r.test.library.stats.TestSplineFunctions.basicSplineCoef#
+#.Call(stats:::C_SplineCoef, 1, list(1), c(1))
+$method
+[1] 1
+
+$n
+[1] 1
+
+$x
+[1] 1
+
+$y
+[1] 1
+
+$b
+[1] 0
+
+$c
+[1] 0
+
+$d
+[1] 0
+
+
+##com.oracle.truffle.r.test.library.stats.TestSplineFunctions.basicSplineCoef#
+#.Call(stats:::C_SplineCoef, 111, c(1:5), c(1:5))
+$method
+[1] 111
+
+$n
+[1] 5
+
+$x
+[1] 1 2 3 4 5
+
+$y
+[1] 1 2 3 4 5
+
+$b
+[1] 0 0 0 0 0
+
+$c
+[1] 0 0 0 0 0
+
+$d
+[1] 0 0 0 0 0
+
+
+##com.oracle.truffle.r.test.library.stats.TestSplineFunctions.basicSplineCoef#
+#.Call(stats:::C_SplineCoef, 2, c(1), c(1))
+$method
+[1] 2
+
+$n
+[1] 1
+
+$x
+[1] 1
+
+$y
+[1] 1
+
+$b
+[1] 0
+
+$c
+[1] 0
+
+$d
+[1] 0
+
+
+##com.oracle.truffle.r.test.library.stats.TestSplineFunctions.basicSplineCoef#
+#.Call(stats:::C_SplineCoef, 2, c(1:5), c(1:5))
+$method
+[1] 2
+
+$n
+[1] 5
+
+$x
+[1] 1 2 3 4 5
+
+$y
+[1] 1 2 3 4 5
+
+$b
+[1] 1 1 1 1 1
+
+$c
+[1] 0 0 0 0 0
+
+$d
+[1] 0 0 0 0 0
+
+
+##com.oracle.truffle.r.test.library.stats.TestSplineFunctions.basicSplineCoef#
+#.Call(stats:::C_SplineCoef, 3, c(1:5), c(1:5))
+$method
+[1] 3
+
+$n
+[1] 5
+
+$x
+[1] 1 2 3 4 5
+
+$y
+[1] 1 2 3 4 5
+
+$b
+[1] 1 1 1 1 1
+
+$c
+[1] 0 0 0 0 0
+
+$d
+[1] 0 0 0 0 0
+
+
+##com.oracle.truffle.r.test.library.stats.TestSplineFunctions.basicSplineCoef#
+#.Call(stats:::C_SplineCoef, 4, c(1:5), c(1:5))
+$method
+[1] 4
+
+$n
+[1] 5
+
+$x
+[1] 1 2 3 4 5
+
+$y
+[1] 1 2 3 4 5
+
+$b
+[1] 0 0 0 0 0
+
+$c
+[1] 0 0 0 0 0
+
+$d
+[1] 0 0 0 0 0
+
+
+##com.oracle.truffle.r.test.library.stats.TestSplineFunctions.basicSplineCoef#
+#.Call(stats:::C_SplineCoef, NA, c(1:5), c(1:5))
+$method
+[1] NA
+
+$n
+[1] 5
+
+$x
+[1] 1 2 3 4 5
+
+$y
+[1] 1 2 3 4 5
+
+$b
+[1] 0 0 0 0 0
+
+$c
+[1] 0 0 0 0 0
+
+$d
+[1] 0 0 0 0 0
+
+
+##com.oracle.truffle.r.test.library.stats.TestSplineFunctions.basicSplineCoef#
+#.Call(stats:::C_SplineCoef, NULL, c(1:5), c(1:5))
+$method
+[1] NA
+
+$n
+[1] 5
+
+$x
+[1] 1 2 3 4 5
+
+$y
+[1] 1 2 3 4 5
+
+$b
+[1] 0 0 0 0 0
+
+$c
+[1] 0 0 0 0 0
+
+$d
+[1] 0 0 0 0 0
+
+
+##com.oracle.truffle.r.test.library.stats.TestSplineFunctions.basicSplineCoef#Ignored.WrongCaller#
+#.Call(stats:::C_SplineCoef, c('a'), c(1), c(1))
+$method
+[1] NA
+
+$n
+[1] 1
+
+$x
+[1] 1
+
+$y
+[1] 1
+
+$b
+[1] 0
+
+$c
+[1] 0
+
+$d
+[1] 0
+
+Warning message:
+NAs introduced by coercion
+
+##com.oracle.truffle.r.test.library.stats.TestSplineFunctions.basicSplineCoef#
+#.Call(stats:::C_SplineCoef, c(), c(1:5), c(1:5))
+$method
+[1] NA
+
+$n
+[1] 5
+
+$x
+[1] 1 2 3 4 5
+
+$y
+[1] 1 2 3 4 5
+
+$b
+[1] 0 0 0 0 0
+
+$c
+[1] 0 0 0 0 0
+
+$d
+[1] 0 0 0 0 0
+
+
+##com.oracle.truffle.r.test.library.stats.TestSplineFunctions.basicSplineCoef#
+#.Call(stats:::C_SplineCoef, c(1), c(1:5), c(1:5))
+$method
+[1] 1
+
+$n
+[1] 5
+
+$x
+[1] 1 2 3 4 5
+
+$y
+[1] 1 2 3 4 5
+
+$b
+[1] 0 0 0 0 0
+
+$c
+[1] 0 0 0 0 0
+
+$d
+[1] 0 0 0 0 0
+
+
+##com.oracle.truffle.r.test.library.stats.TestSplineFunctions.basicSplineCoef#
+#.Call(stats:::C_SplineCoef, c(1, 2, 3), c(1), c(1))
+$method
+[1] 1
+
+$n
+[1] 1
+
+$x
+[1] 1
+
+$y
+[1] 1
+
+$b
+[1] 0
+
+$c
+[1] 0
+
+$d
+[1] 0
+
+
+##com.oracle.truffle.r.test.library.stats.TestSplineFunctions.basicSplineCoef#
+#.Call(stats:::C_SplineCoef, c(list()), c(1:5), c(1:5))
+$method
+[1] NA
+
+$n
+[1] 5
+
+$x
+[1] 1 2 3 4 5
+
+$y
+[1] 1 2 3 4 5
+
+$b
+[1] 0 0 0 0 0
+
+$c
+[1] 0 0 0 0 0
+
+$d
+[1] 0 0 0 0 0
+
+
+##com.oracle.truffle.r.test.library.stats.TestSplineFunctions.basicSplineCoef#Ignored.WrongCaller#
+#.Call(stats:::C_SplineCoef, environment(), c(1:5), c(1:5))
+$method
+[1] NA
+
+$n
+[1] 5
+
+$x
+[1] 1 2 3 4 5
+
+$y
+[1] 1 2 3 4 5
+
+$b
+[1] 0 0 0 0 0
+
+$c
+[1] 0 0 0 0 0
+
+$d
+[1] 0 0 0 0 0
+
+
+##com.oracle.truffle.r.test.library.stats.TestSplineFunctions.basicSplineCoef#Ignored.WrongCaller#
+#.Call(stats:::C_SplineCoef, function() {}, c(1:5), c(1:5))
+$method
+[1] NA
+
+$n
+[1] 5
+
+$x
+[1] 1 2 3 4 5
+
+$y
+[1] 1 2 3 4 5
+
+$b
+[1] 0 0 0 0 0
+
+$c
+[1] 0 0 0 0 0
+
+$d
+[1] 0 0 0 0 0
+
+
+##com.oracle.truffle.r.test.library.stats.TestSplineFunctions.basicSplineCoef#
+#.Call(stats:::C_SplineCoef, list(), c(1:5), c(1:5))
+$method
+[1] NA
+
+$n
+[1] 5
+
+$x
+[1] 1 2 3 4 5
+
+$y
+[1] 1 2 3 4 5
+
+$b
+[1] 0 0 0 0 0
+
+$c
+[1] 0 0 0 0 0
+
+$d
+[1] 0 0 0 0 0
+
+
+##com.oracle.truffle.r.test.library.stats.TestSplineFunctions.basicSplineCoef#Ignored.WrongCaller#
+#.Call(stats:::C_SplineCoef, list(1), c(1), c(1))
+$method
+[1] NA
+
+$n
+[1] 1
+
+$x
+[1] 1
+
+$y
+[1] 1
+
+$b
+[1] 0
+
+$c
+[1] 0
+
+$d
+[1] 0
+
+
 ##com.oracle.truffle.r.test.library.stats.TestStatFunctions.testFunctions21#Output.IgnoreWhitespace#
 #set.seed(1); dchisq(0, c(0.0653, 0.000123, 32e-80, 8833, 79e70, 0, -1), log=FALSE)
 [1] Inf Inf Inf   0   0 Inf NaN
@@ -137702,6 +138598,130 @@ Levels: 2147483648L
 #type.convert('NA', 1)
 Error in type.convert("NA", 1) : invalid 'na.strings' argument
 
+##com.oracle.truffle.r.test.library.utils.TestTypeConvert.typeConvertExternal2Test#
+#.External2(utils:::C_typeconvert, NA, 'NA', FALSE, '.', 'allow.loss')
+Error: the first argument must be of mode character
+
+##com.oracle.truffle.r.test.library.utils.TestTypeConvert.typeConvertExternal2Test#
+#.External2(utils:::C_typeconvert, NULL, 'NA', FALSE, '.', 'allow.loss')
+Error: the first argument must be of mode character
+
+##com.oracle.truffle.r.test.library.utils.TestTypeConvert.typeConvertExternal2Test#
+#.External2(utils:::C_typeconvert, c('1'), 'NA', 'TRUE', '.', 'allow.loss')
+[1] 1
+
+##com.oracle.truffle.r.test.library.utils.TestTypeConvert.typeConvertExternal2Test#
+#.External2(utils:::C_typeconvert, c('1'), 'NA', 'abc', '.', 'allow.loss')
+[1] 1
+
+##com.oracle.truffle.r.test.library.utils.TestTypeConvert.typeConvertExternal2Test#
+#.External2(utils:::C_typeconvert, c('1'), 'NA', 1, '.', 'allow.loss')
+[1] 1
+
+##com.oracle.truffle.r.test.library.utils.TestTypeConvert.typeConvertExternal2Test#
+#.External2(utils:::C_typeconvert, c('1'), 'NA', 2, '.', 'allow.loss')
+[1] 1
+
+##com.oracle.truffle.r.test.library.utils.TestTypeConvert.typeConvertExternal2Test#
+#.External2(utils:::C_typeconvert, c('1'), 'NA', FALSE, '.', 'allow.loss')
+[1] 1
+
+##com.oracle.truffle.r.test.library.utils.TestTypeConvert.typeConvertExternal2Test#
+#.External2(utils:::C_typeconvert, c('1'), 'NA', NA, '.', 'allow.loss')
+[1] 1
+
+##com.oracle.truffle.r.test.library.utils.TestTypeConvert.typeConvertExternal2Test#
+#.External2(utils:::C_typeconvert, c('1'), 'NA', NULL, '.', 'allow.loss')
+[1] 1
+
+##com.oracle.truffle.r.test.library.utils.TestTypeConvert.typeConvertExternal2Test#
+#.External2(utils:::C_typeconvert, c('1'), 'NA', c(), '.', 'allow.loss')
+[1] 1
+
+##com.oracle.truffle.r.test.library.utils.TestTypeConvert.typeConvertExternal2Test#
+#.External2(utils:::C_typeconvert, c('1'), 'NA', c(NULL), '.', 'allow.loss')
+[1] 1
+
+##com.oracle.truffle.r.test.library.utils.TestTypeConvert.typeConvertExternal2Test#
+#.External2(utils:::C_typeconvert, c('1'), 'NA', environment(), '.', 'allow.loss')
+[1] 1
+
+##com.oracle.truffle.r.test.library.utils.TestTypeConvert.typeConvertExternal2Test#
+#.External2(utils:::C_typeconvert, c('1'), 'NA', function() {}, '.', 'allow.loss')
+[1] 1
+
+##com.oracle.truffle.r.test.library.utils.TestTypeConvert.typeConvertExternal2Test#
+#.External2(utils:::C_typeconvert, c('1'), 'NA', list('abc'), '.', 'allow.loss')
+[1] 1
+
+##com.oracle.truffle.r.test.library.utils.TestTypeConvert.typeConvertExternal2Test#
+#.External2(utils:::C_typeconvert, c('1'), 'NA', list(), '.', 'allow.loss')
+[1] 1
+
+##com.oracle.truffle.r.test.library.utils.TestTypeConvert.typeConvertExternal2Test#
+#.External2(utils:::C_typeconvert, c('1'), NA, FALSE, '.', 'allow.loss')
+Error: invalid 'na.strings' argument
+
+##com.oracle.truffle.r.test.library.utils.TestTypeConvert.typeConvertExternal2Test#
+#.External2(utils:::C_typeconvert, c('1'), NULL, FALSE, '.', 'allow.loss')
+Error: invalid 'na.strings' argument
+
+##com.oracle.truffle.r.test.library.utils.TestTypeConvert.typeConvertExternal2Test#
+#.External2(utils:::C_typeconvert, c('1'), c(), FALSE, '.', 'allow.loss')
+Error: invalid 'na.strings' argument
+
+##com.oracle.truffle.r.test.library.utils.TestTypeConvert.typeConvertExternal2Test#
+#.External2(utils:::C_typeconvert, c('1'), c(1), FALSE, '.', 'allow.loss')
+Error: invalid 'na.strings' argument
+
+##com.oracle.truffle.r.test.library.utils.TestTypeConvert.typeConvertExternal2Test#
+#.External2(utils:::C_typeconvert, c('1'), environment(), FALSE, '.', 'allow.loss')
+Error: invalid 'na.strings' argument
+
+##com.oracle.truffle.r.test.library.utils.TestTypeConvert.typeConvertExternal2Test#
+#.External2(utils:::C_typeconvert, c(), 'NA', FALSE, '.', 'allow.loss')
+Error: the first argument must be of mode character
+
+##com.oracle.truffle.r.test.library.utils.TestTypeConvert.typeConvertExternal2Test#
+#.External2(utils:::C_typeconvert, c(1), c(1), FALSE, '.', 'allow.loss')
+Error: the first argument must be of mode character
+
+##com.oracle.truffle.r.test.library.utils.TestTypeConvert.typeConvertExternal2Test#
+#.External2(utils:::C_typeconvert, c(1, '1'), c(1), FALSE, '.', 'allow.loss')
+Error: invalid 'na.strings' argument
+
+##com.oracle.truffle.r.test.library.utils.TestTypeConvert.typeConvertExternal2Test#
+#.External2(utils:::C_typeconvert, c(1, 'TRUE'), c(1), FALSE, '.', 'allow.loss')
+Error: invalid 'na.strings' argument
+
+##com.oracle.truffle.r.test.library.utils.TestTypeConvert.typeConvertExternal2Test#
+#.External2(utils:::C_typeconvert, c(1, 'TRUE', 'x'), c(1), FALSE, '.', 'allow.loss')
+Error: invalid 'na.strings' argument
+
+##com.oracle.truffle.r.test.library.utils.TestTypeConvert.typeConvertExternal2Test#
+#.External2(utils:::C_typeconvert, c(1, 'x'), c(1), FALSE, '.', 'allow.loss')
+Error: invalid 'na.strings' argument
+
+##com.oracle.truffle.r.test.library.utils.TestTypeConvert.typeConvertExternal2Test#
+#.External2(utils:::C_typeconvert, c(1, TRUE), c(1), FALSE, '.', 'allow.loss')
+Error: the first argument must be of mode character
+
+##com.oracle.truffle.r.test.library.utils.TestTypeConvert.typeConvertExternal2Test#
+#.External2(utils:::C_typeconvert, environment(), 'NA', FALSE, '.', 'allow.loss')
+Error: the first argument must be of mode character
+
+##com.oracle.truffle.r.test.library.utils.TestTypeConvert.typeConvertExternal2Test#
+#.External2(utils:::C_typeconvert, list('1'), list('1'), FALSE, '.', 'allow.loss')
+Error: the first argument must be of mode character
+
+##com.oracle.truffle.r.test.library.utils.TestTypeConvert.typeConvertExternal2Test#
+#.External2(utils:::C_typeconvert, list('1'), list(1), FALSE, '.', 'allow.loss')
+Error: the first argument must be of mode character
+
+##com.oracle.truffle.r.test.library.utils.TestTypeConvert.typeConvertExternal2Test#
+#.External2(utils:::C_typeconvert, list(1), list(1), FALSE, '.', 'allow.loss')
+Error: the first argument must be of mode character
+
 ##com.oracle.truffle.r.test.library.utils.TestUtils.testHeadNTail#
 #{head(letters)}
 [1] "a" "b" "c" "d" "e" "f"
diff --git a/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/builtins/TestBuiltin_substitute.java b/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/builtins/TestBuiltin_substitute.java
index 871968ec0b811ebe9dffe454d5791e2022bde4bf..ad2e9940d396e8865d77cb87da8e0c412f93eee5 100644
--- a/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/builtins/TestBuiltin_substitute.java
+++ b/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/builtins/TestBuiltin_substitute.java
@@ -87,5 +87,30 @@ public class TestBuiltin_substitute extends TestBase {
         assertEval("f<-function(x,name) substitute(x$name <- 5); f(foo, bar); foo <- new.env(); eval(f(foo,bar)); foo$bar");
         assertEval("f<-function(x,name) substitute(x@name); f(foo, bar); setClass('cl', representation(bar='numeric')); foo <- new('cl'); foo@bar <- 1; eval(f(foo,bar))");
         assertEval("f<-function(x,name) substitute(x@name <- 5); f(foo, bar); setClass('cl', representation(bar='numeric')); foo <- new('cl'); eval(f(foo,bar)); foo@bar");
+
+        assertEval("substitute(1, 1)");
+        assertEval("substitute(1, 1, 1)");
+        assertEval("substitute(expr=1, env=1)");
+
+        assertEval("substitute(1, NULL)");
+        assertEval("substitute(1, NA)");
+        assertEval("substitute(1, c(list(1)))");
+        assertEval("substitute(1, list(c(list(1))))");
+        assertEval("substitute(1, list(list(1)))");
+
+        assertEval("a<-substitute(quote(x+1), NULL); a");
+        assertEval("a<-substitute(quote(x+1), NA); a");
+        assertEval("a<-substitute(quote(x+1), list(1)); a");
+        assertEval("a<-substitute(quote(x+1), list(x=1)); a");
+        assertEval("a<-substitute(quote(x+1), list(y=1)); a");
+        assertEval("a<-substitute(quote(x+1), c(list(x=1), 'breakme')); a");
+        assertEval("a<-substitute(quote(x+1), c(c(list(x=1)))); a");
+        assertEval("a<-substitute(quote(x+1), list(c(c(list(x=1))))); a");
+        assertEval("a<-substitute(quote(x+1), list(list(x=1))); a");
+        assertEval("a<-substitute(quote(x+1), c(list(x=1, 1))); a");
+        assertEval("a<-substitute(quote(x+y), c(list(x=1), list(y=1))); a");
+        assertEval("substitute(quote(x+1), environment())");
+        assertEval("f<-function() {}; substitute(quote(x+1), f)");
+        assertEval("substitute(quote(x+1), setClass('a'))");
     }
 }
diff --git a/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/library/methods/TestSubstituteDirect.java b/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/library/methods/TestSubstituteDirect.java
new file mode 100644
index 0000000000000000000000000000000000000000..4ab7f98157a5087cf473adfec54580e8095dfe32
--- /dev/null
+++ b/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/library/methods/TestSubstituteDirect.java
@@ -0,0 +1,75 @@
+/*
+ * 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.test.library.methods;
+
+import org.junit.Test;
+
+import com.oracle.truffle.r.test.TestBase;
+
+public class TestSubstituteDirect extends TestBase {
+
+    @Test
+    public void basicTests() {
+        assertEval("substituteDirect(NULL, list(x=1))");
+        assertEval("substituteDirect(NA, list(x=1))");
+        assertEval("substituteDirect(environment(), list(x=1))");
+        assertEval("substituteDirect(1, 1)");
+        assertEval("substituteDirect(1, 1, 1)");
+        assertEval("substituteDirect(object=1, frame=1)");
+        assertEval("substituteDirect(object=1, frame=1, cleanFunction=1)");
+
+        assertEval("substituteDirect(1, frame=NULL)");
+        assertEval("substituteDirect(1, frame=NA)");
+        assertEval("substituteDirect(object=1, frame=c(list(1)))");
+        assertEval("substituteDirect(object=1, frame=list(c(list(1))))");
+        assertEval("substituteDirect(object=1, frame=list(list(1)))");
+
+        assertEval("a<-substituteDirect(quote(x+1), NULL); a");
+        assertEval("a<-substituteDirect(quote(x+1), NA); a");
+        assertEval("a<-substituteDirect(quote(x+1), list(1)); a");
+        assertEval("a<-substituteDirect(quote(x+1), list(x=1)); a");
+        assertEval("a<-substituteDirect(quote(x+1), list(y=1)); a");
+        assertEval("a<-substituteDirect(quote(x+1), c(list(x=1), 'breakme')); a");
+        assertEval("a<-substituteDirect(quote(x+1), c(c(list(x=1)))); a");
+        assertEval("a<-substituteDirect(quote(x+1), list(c(c(list(x=1))))); a");
+        assertEval("a<-substituteDirect(quote(x+1), list(list(x=1))); a");
+        assertEval("a<-substituteDirect(quote(x+1), c(list(x=1, 1))); a");
+        assertEval("a<-substituteDirect(quote(x+y), c(list(x=1), list(y=1))); a");
+        assertEval("substituteDirect(quote(x+1), frame=environment())");
+        assertEval("f<-function() {}; substituteDirect(quote(x+1), frame=f)");
+        assertEval("substituteDirect(quote(x+1), frame=setClass('a'))");
+
+        assertEval("substituteDirect(quote(x+1), list(x=1), cleanFunction=TRUE)");
+        assertEval("substituteDirect(quote(x+1), list(x=1), cleanFunction=c(TRUE, 'breakme'))");
+        assertEval("substituteDirect(quote(x+1), list(x=1), cleanFunction=c(c(TRUE, 'breakme')))");
+        assertEval("substituteDirect(quote(x+1), list(x=1), cleanFunction=c(TRUE, FALSE))");
+        assertEval("substituteDirect(quote(x+1), list(x=1), cleanFunction=list(c(TRUE), 'breakme'))");
+        assertEval("substituteDirect(quote(x+1), list(x=1), cleanFunction=NA)");
+        assertEval("substituteDirect(quote(x+1), list(x=1), cleanFunction=NULL)");
+        assertEval("substituteDirect(quote(x+1), list(x=1), cleanFunction='a')");
+        assertEval("substituteDirect(quote(x+1), list(x=1), cleanFunction=c('1'))");
+        assertEval("substituteDirect(quote(x+1), list(x=1), cleanFunction=c(1))");
+        assertEval("substituteDirect(quote(x+1), list(x=1), cleanFunction=environment())");
+    }
+
+}
diff --git a/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/library/stats/TestSplineFunctions.java b/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/library/stats/TestSplineFunctions.java
new file mode 100644
index 0000000000000000000000000000000000000000..defaaa8812de51da17c89a5eda3e7778328c7f41
--- /dev/null
+++ b/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/library/stats/TestSplineFunctions.java
@@ -0,0 +1,71 @@
+/*
+ * 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.test.library.stats;
+
+import org.junit.Test;
+
+import com.oracle.truffle.r.test.TestBase;
+
+public class TestSplineFunctions extends TestBase {
+
+    @Test
+    public void basicSplineCoef() {
+        // method "periodic"
+        assertEval(".Call(stats:::C_SplineCoef, 1, c(1), c(1))");
+        assertEval(".Call(stats:::C_SplineCoef, 1, c(1:5), c(1:5))");
+        assertEval(".Call(stats:::C_SplineCoef, 1, c(1:6), c(1:5, 1))");
+        // method "natural"
+        assertEval(".Call(stats:::C_SplineCoef, 2, c(1), c(1))");
+        assertEval(".Call(stats:::C_SplineCoef, 2, c(1:5), c(1:5))");
+        // method "fmm"
+        assertEval(".Call(stats:::C_SplineCoef, 3, c(1:5), c(1:5))");
+        // method "hyman"
+        assertEval(".Call(stats:::C_SplineCoef, 4, c(1:5), c(1:5))");
+
+        assertEval(".Call(stats:::C_SplineCoef, 0, c(1:5), c(1:5))");
+        assertEval(".Call(stats:::C_SplineCoef, -1, c(1:5), c(1:5))");
+        assertEval(".Call(stats:::C_SplineCoef, 111, c(1:5), c(1:5))");
+
+        assertEval(".Call(stats:::C_SplineCoef, NULL, c(1:5), c(1:5))");
+        assertEval(".Call(stats:::C_SplineCoef, NA, c(1:5), c(1:5))");
+        assertEval(".Call(stats:::C_SplineCoef, c(), c(1:5), c(1:5))");
+        assertEval(".Call(stats:::C_SplineCoef, list(), c(1:5), c(1:5))");
+        assertEval(".Call(stats:::C_SplineCoef, c(list()), c(1:5), c(1:5))");
+        assertEval(Ignored.WrongCaller, ".Call(stats:::C_SplineCoef, 'abc', c(1:5), c(1:5))");
+        assertEval(".Call(stats:::C_SplineCoef, c(1), c(1:5), c(1:5))");
+        assertEval(".Call(stats:::C_SplineCoef, c(1, 2, 3), c(1), c(1))");
+        assertEval(Ignored.WrongCaller, ".Call(stats:::C_SplineCoef, c('a'), c(1), c(1))");
+        assertEval(Ignored.WrongCaller, ".Call(stats:::C_SplineCoef, list(1), c(1), c(1))");
+        assertEval(Ignored.WrongCaller, ".Call(stats:::C_SplineCoef, environment(), c(1:5), c(1:5))");
+        assertEval(Ignored.WrongCaller, ".Call(stats:::C_SplineCoef, function() {}, c(1:5), c(1:5))");
+        assertEval(".Call(stats:::C_SplineCoef, 1, list(1), c(1))");
+        assertEval(".Call(stats:::C_SplineCoef, 1, c(1), list(1))");
+
+        assertEval(".Call(stats:::C_SplineCoef, 1, NULL, c(1:5))");
+        assertEval(".Call(stats:::C_SplineCoef, 1, NA, c(1:5))");
+        assertEval(".Call(stats:::C_SplineCoef, 1, c(1:5), NULL)");
+        assertEval(".Call(stats:::C_SplineCoef, 1, c(1:5), NA)");
+        assertEval(".Call(stats:::C_SplineCoef, 1, NULL, NULL)");
+        assertEval(".Call(stats:::C_SplineCoef, 1, NA, NA)");
+    }
+}
diff --git a/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/library/utils/TestTypeConvert.java b/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/library/utils/TestTypeConvert.java
index 972ac0da24429ada9a1df550e8466f806b13cf2b..2096f7059b4ef0e12eea62f1a015cfda8ef4bb88 100644
--- a/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/library/utils/TestTypeConvert.java
+++ b/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/library/utils/TestTypeConvert.java
@@ -58,4 +58,41 @@ public class TestTypeConvert extends TestBase {
         // UnsupportedSpecializationException: Unexpected values provided for ...
         assertEval(Ignored.Unimplemented, "type.convert('NA', 1)");
     }
+
+    @Test
+    public void typeConvertExternal2Test() {
+        assertEval(".External2(utils:::C_typeconvert, c('1'), 'NA', FALSE, '.', 'allow.loss')");
+        assertEval(".External2(utils:::C_typeconvert, c('1'), 'NA', NA, '.', 'allow.loss')");
+        assertEval(".External2(utils:::C_typeconvert, c('1'), 'NA', NULL, '.', 'allow.loss')");
+        assertEval(".External2(utils:::C_typeconvert, c('1'), 'NA', 'TRUE', '.', 'allow.loss')");
+        assertEval(".External2(utils:::C_typeconvert, c('1'), 'NA', 'abc', '.', 'allow.loss')");
+        assertEval(".External2(utils:::C_typeconvert, c('1'), 'NA', list('abc'), '.', 'allow.loss')");
+        assertEval(".External2(utils:::C_typeconvert, c('1'), 'NA', list(), '.', 'allow.loss')");
+        assertEval(".External2(utils:::C_typeconvert, c('1'), 'NA', c(), '.', 'allow.loss')");
+        assertEval(".External2(utils:::C_typeconvert, c('1'), 'NA', c(NULL), '.', 'allow.loss')");
+        assertEval(".External2(utils:::C_typeconvert, c('1'), 'NA', 1, '.', 'allow.loss')");
+        assertEval(".External2(utils:::C_typeconvert, c('1'), 'NA', 2, '.', 'allow.loss')");
+        assertEval(".External2(utils:::C_typeconvert, c('1'), 'NA', environment(), '.', 'allow.loss')");
+        assertEval(".External2(utils:::C_typeconvert, c('1'), 'NA', function() {}, '.', 'allow.loss')");
+
+        assertEval(".External2(utils:::C_typeconvert, NULL, 'NA', FALSE, '.', 'allow.loss')");
+        assertEval(".External2(utils:::C_typeconvert, NA, 'NA', FALSE, '.', 'allow.loss')");
+        assertEval(".External2(utils:::C_typeconvert, c(), 'NA', FALSE, '.', 'allow.loss')");
+        assertEval(".External2(utils:::C_typeconvert, c('1'), NULL, FALSE, '.', 'allow.loss')");
+        assertEval(".External2(utils:::C_typeconvert, c('1'), NA, FALSE, '.', 'allow.loss')");
+        assertEval(".External2(utils:::C_typeconvert, c('1'), c(), FALSE, '.', 'allow.loss')");
+        assertEval(".External2(utils:::C_typeconvert, c(1), c(1), FALSE, '.', 'allow.loss')");
+        assertEval(".External2(utils:::C_typeconvert, c(1, TRUE), c(1), FALSE, '.', 'allow.loss')");
+        assertEval(".External2(utils:::C_typeconvert, c(1, 'TRUE'), c(1), FALSE, '.', 'allow.loss')");
+        assertEval(".External2(utils:::C_typeconvert, c(1, 'TRUE', 'x'), c(1), FALSE, '.', 'allow.loss')");
+        assertEval(".External2(utils:::C_typeconvert, c(1, '1'), c(1), FALSE, '.', 'allow.loss')");
+        assertEval(".External2(utils:::C_typeconvert, c(1, 'x'), c(1), FALSE, '.', 'allow.loss')");
+        assertEval(".External2(utils:::C_typeconvert, c('1'), c(1), FALSE, '.', 'allow.loss')");
+        assertEval(".External2(utils:::C_typeconvert, list(1), list(1), FALSE, '.', 'allow.loss')");
+        assertEval(".External2(utils:::C_typeconvert, list('1'), list('1'), FALSE, '.', 'allow.loss')");
+        assertEval(".External2(utils:::C_typeconvert, list('1'), list(1), FALSE, '.', 'allow.loss')");
+        assertEval(".External2(utils:::C_typeconvert, environment(), 'NA', FALSE, '.', 'allow.loss')");
+        assertEval(".External2(utils:::C_typeconvert, c('1'), environment(), FALSE, '.', 'allow.loss')");
+    }
+
 }
diff --git a/mx.fastr/mx_fastr.py b/mx.fastr/mx_fastr.py
index e215042965f7cf0e19a08b2e8fc922706aa32c4d..5e9c6ebfd3344ee1405840869061861a8af54bc6 100644
--- a/mx.fastr/mx_fastr.py
+++ b/mx.fastr/mx_fastr.py
@@ -407,7 +407,7 @@ def _test_subpackage(name):
     return '.'.join((_test_package(), name))
 
 def _simple_generated_unit_tests():
-    return ','.join(map(_test_subpackage, ['library.base', 'library.grid', 'library.stats', 'library.utils', 'library.fastr', 'builtins', 'functions', 'parser', 'S4', 'rng', 'runtime.data']))
+    return ','.join(map(_test_subpackage, ['library.base', 'library.grid', 'library.methods', 'library.stats', 'library.utils', 'library.fastr', 'builtins', 'functions', 'parser', 'S4', 'rng', 'runtime.data']))
 
 def _simple_unit_tests():
     return ','.join([_simple_generated_unit_tests(), _test_subpackage('tck')])