diff --git a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/NZChar.java b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/NZChar.java
index 2400bc8fe76c7070f0f6fd940073e6772e22f7af..03a1d92243a754ff346a19caf9acf344ecc16d13 100644
--- a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/NZChar.java
+++ b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/NZChar.java
@@ -22,32 +22,27 @@
  */
 package com.oracle.truffle.r.nodes.builtin.base;
 
+import static com.oracle.truffle.r.nodes.builtin.CastBuilder.Predef.toBoolean;
 import static com.oracle.truffle.r.runtime.builtins.RBehavior.PURE;
 import static com.oracle.truffle.r.runtime.builtins.RBuiltinKind.PRIMITIVE;
 
-import com.oracle.truffle.api.CompilerDirectives;
 import com.oracle.truffle.api.dsl.Specialization;
+import com.oracle.truffle.r.nodes.builtin.CastBuilder;
 import com.oracle.truffle.r.nodes.builtin.RBuiltinNode;
-import com.oracle.truffle.r.nodes.unary.CastStringNode;
-import com.oracle.truffle.r.nodes.unary.CastStringNodeGen;
 import com.oracle.truffle.r.runtime.RRuntime;
 import com.oracle.truffle.r.runtime.builtins.RBuiltin;
 import com.oracle.truffle.r.runtime.data.RDataFactory;
 import com.oracle.truffle.r.runtime.data.RLogicalVector;
 import com.oracle.truffle.r.runtime.data.RNull;
-import com.oracle.truffle.r.runtime.data.RStringVector;
-import com.oracle.truffle.r.runtime.data.model.RAbstractVector;
+import com.oracle.truffle.r.runtime.data.model.RAbstractStringVector;
 
-@RBuiltin(name = "nzchar", kind = PRIMITIVE, parameterNames = {"x"}, behavior = PURE)
+@RBuiltin(name = "nzchar", kind = PRIMITIVE, parameterNames = {"x", "keepNA"}, behavior = PURE)
 public abstract class NZChar extends RBuiltinNode {
-    @Child private CastStringNode convertString;
 
-    private String coerceContent(Object content) {
-        if (convertString == null) {
-            CompilerDirectives.transferToInterpreterAndInvalidate();
-            convertString = insert(CastStringNodeGen.create(false, false, false));
-        }
-        return (String) convertString.execute(content);
+    @Override
+    protected void createCasts(CastBuilder casts) {
+        casts.arg("x").asStringVector();
+        casts.arg("keepNA").asLogicalVector().findFirst(RRuntime.LOGICAL_FALSE).map(toBoolean());
     }
 
     private static byte isNonZeroLength(String s) {
@@ -55,42 +50,23 @@ public abstract class NZChar extends RBuiltinNode {
     }
 
     @Specialization
-    protected RLogicalVector rev(@SuppressWarnings("unused") RNull value) {
+    protected RLogicalVector rev(RNull value, boolean keepNA) {
         return RDataFactory.createEmptyLogicalVector();
     }
 
     @Specialization
-    protected byte rev(int value) {
-        return isNonZeroLength(coerceContent(value));
-    }
-
-    @Specialization
-    protected byte rev(double value) {
-        return isNonZeroLength(coerceContent(value));
-    }
-
-    @Specialization
-    protected byte rev(byte value) {
-        return isNonZeroLength(coerceContent(value));
-    }
-
-    @Specialization
-    protected RLogicalVector rev(RStringVector vector) {
-        int len = vector.getLength();
-        byte[] result = new byte[len];
-        for (int i = 0; i < len; i++) {
-            result[i] = isNonZeroLength(vector.getDataAt(i));
-        }
-        return RDataFactory.createLogicalVector(result, RDataFactory.COMPLETE_VECTOR);
-    }
-
-    @Specialization
-    protected RLogicalVector rev(RAbstractVector vector) {
+    protected RLogicalVector rev(RAbstractStringVector vector, boolean keepNA) {
         int len = vector.getLength();
         byte[] result = new byte[len];
+        boolean hasNA = false;
         for (int i = 0; i < len; i++) {
-            result[i] = isNonZeroLength(coerceContent(vector.getDataAtAsObject(i)));
+            if (keepNA && RRuntime.isNA(vector.getDataAt(i))) {
+                result[i] = RRuntime.LOGICAL_NA;
+                hasNA = true;
+            } else {
+                result[i] = isNonZeroLength(vector.getDataAt(i));
+            }
         }
-        return RDataFactory.createLogicalVector(result, RDataFactory.COMPLETE_VECTOR);
+        return RDataFactory.createLogicalVector(result, /* complete: */ keepNA && !hasNA);
     }
 }
diff --git a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/Order.java b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/Order.java
index 35132b07c91e675949d1117f6319f9e9954205e7..b0207c785bc8598ea96387f0b36d8b3aeb8834ae 100644
--- a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/Order.java
+++ b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/Order.java
@@ -12,6 +12,9 @@
  */
 package com.oracle.truffle.r.nodes.builtin.base;
 
+import static com.oracle.truffle.r.nodes.builtin.CastBuilder.Predef.numericValue;
+import static com.oracle.truffle.r.nodes.builtin.CastBuilder.Predef.toBoolean;
+import static com.oracle.truffle.r.runtime.RError.Message.INVALID_LOGICAL;
 import static com.oracle.truffle.r.runtime.builtins.RBehavior.PURE;
 import static com.oracle.truffle.r.runtime.builtins.RBuiltinKind.INTERNAL;
 
@@ -85,7 +88,8 @@ public abstract class Order extends RPrecedenceBuiltinNode {
 
     @Override
     protected void createCasts(CastBuilder casts) {
-        casts.firstBoolean(0, "na.last").firstBoolean(1, "decreasing");
+        casts.arg("na.last").mustBe(numericValue(), INVALID_LOGICAL, "na.last").asLogicalVector().findFirst().map(toBoolean());
+        casts.arg("decreasing").mustBe(numericValue(), INVALID_LOGICAL, "decreasing").asLogicalVector().findFirst().map(toBoolean());
     }
 
     private int cmp(Object v, int i, int j, boolean naLast) {
diff --git a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/PMatch.java b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/PMatch.java
index 3bc987dd1af7768ab0d8bcaa9915e4efc7d7d21c..c130b43d8d06a782bd9db21a384281ff2a56f34b 100644
--- a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/PMatch.java
+++ b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/PMatch.java
@@ -22,6 +22,10 @@
  */
 package com.oracle.truffle.r.nodes.builtin.base;
 
+import static com.oracle.truffle.r.nodes.builtin.CastBuilder.Predef.constant;
+import static com.oracle.truffle.r.nodes.builtin.CastBuilder.Predef.nullValue;
+import static com.oracle.truffle.r.nodes.builtin.CastBuilder.Predef.numericValue;
+import static com.oracle.truffle.r.nodes.builtin.CastBuilder.Predef.toBoolean;
 import static com.oracle.truffle.r.runtime.builtins.RBehavior.PURE;
 import static com.oracle.truffle.r.runtime.builtins.RBuiltinKind.INTERNAL;
 
@@ -42,14 +46,16 @@ public abstract class PMatch extends RBuiltinNode {
 
     @Override
     protected void createCasts(CastBuilder casts) {
-        casts.toInteger(2).toLogical(3);
+        casts.arg("x").asStringVector();
+        casts.arg("table").asStringVector();
+        casts.arg("nomatch").mapIf(nullValue(), constant(RRuntime.INT_NA)).asIntegerVector();
+        casts.arg("duplicates.ok").mustBe(nullValue().not().and(numericValue())).asLogicalVector().findFirst().map(toBoolean());
     }
 
     @Specialization
-    protected RIntVector doPMatch(RAbstractStringVector x, RAbstractStringVector table, int nomatch, byte duplicatesOk) {
+    protected RIntVector doPMatch(RAbstractStringVector x, RAbstractStringVector table, int nomatch, boolean duplicatesOk) {
         int xl = x.getLength();
         int tl = table.getLength();
-        boolean dupsOk = RRuntime.fromLogical(duplicatesOk);
         int[] matches = new int[xl];
         boolean[] matched = new boolean[xl];
         boolean[] used = new boolean[tl];
@@ -77,7 +83,7 @@ public abstract class PMatch extends RBuiltinNode {
                         if (match) {
                             matches[i] = t + 1;
                             matched[i] = true;
-                            if (!dupsOk) {
+                            if (!duplicatesOk) {
                                 used[t] = true;
                             }
                         }
diff --git a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/PMinMax.java b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/PMinMax.java
index 78b39957ba995d6bbf24687ff2a1f96a8f0cb11f..9ec966bd6e4232087eb7ddecea5e3c90f4a1d2de 100644
--- a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/PMinMax.java
+++ b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/PMinMax.java
@@ -22,13 +22,20 @@
  */
 package com.oracle.truffle.r.nodes.builtin.base;
 
+import static com.oracle.truffle.r.nodes.builtin.CastBuilder.Predef.logicalNA;
+import static com.oracle.truffle.r.nodes.builtin.CastBuilder.Predef.numericValue;
+import static com.oracle.truffle.r.nodes.builtin.CastBuilder.Predef.toBoolean;
+import static com.oracle.truffle.r.runtime.RError.NO_CALLER;
+import static com.oracle.truffle.r.runtime.RError.SHOW_CALLER;
 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.CompilerDirectives;
 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.api.profiles.ConditionProfile;
+import com.oracle.truffle.r.nodes.builtin.CastBuilder;
 import com.oracle.truffle.r.nodes.builtin.RBuiltinNode;
 import com.oracle.truffle.r.nodes.builtin.base.PMinMaxNodeGen.MultiElemStringHandlerNodeGen;
 import com.oracle.truffle.r.nodes.unary.CastDoubleNode;
@@ -45,9 +52,9 @@ import com.oracle.truffle.r.nodes.unary.PrecedenceNodeGen;
 import com.oracle.truffle.r.nodes.unary.UnaryArithmeticReduceNode.ReduceSemantics;
 import com.oracle.truffle.r.runtime.RError;
 import com.oracle.truffle.r.runtime.RRuntime;
+import com.oracle.truffle.r.runtime.RError.Message;
 import com.oracle.truffle.r.runtime.builtins.RBuiltin;
 import com.oracle.truffle.r.runtime.data.RArgsValuesAndNames;
-import com.oracle.truffle.r.runtime.data.RComplexVector;
 import com.oracle.truffle.r.runtime.data.RDataFactory;
 import com.oracle.truffle.r.runtime.data.RDoubleVector;
 import com.oracle.truffle.r.runtime.data.RIntVector;
@@ -83,7 +90,12 @@ public abstract class PMinMax extends RBuiltinNode {
         this.op = factory.create();
     }
 
-    private byte handleString(Object[] argValues, byte naRm, int offset, int ind, int maxLength, byte warning, Object data) {
+    @Override
+    protected void createCasts(CastBuilder casts) {
+        casts.arg("na.rm").defaultError(SHOW_CALLER, Message.INVALID_VALUE, "na.rm").mustBe(numericValue()).asLogicalVector().findFirst().mustBe(logicalNA().not()).map(toBoolean());
+    }
+
+    private byte handleString(Object[] argValues, boolean naRm, int offset, int ind, int maxLength, byte warning, Object data) {
         if (stringHandler == null) {
             CompilerDirectives.transferToInterpreterAndInvalidate();
             stringHandler = insert(MultiElemStringHandlerNodeGen.create(semantics, factory, na));
@@ -141,22 +153,22 @@ public abstract class PMinMax extends RBuiltinNode {
     }
 
     @Specialization(guards = {"isIntegerPrecedence(args)", "args.getLength() == 0"})
-    protected Object pMinMaxNoneVecInt(@SuppressWarnings("unused") byte naRm, @SuppressWarnings("unused") RArgsValuesAndNames args) {
+    protected Object pMinMaxNoneVecInt(@SuppressWarnings("unused") boolean naRm, @SuppressWarnings("unused") RArgsValuesAndNames args) {
         return RDataFactory.createEmptyIntVector();
     }
 
     @Specialization(guards = {"isIntegerPrecedence(args)", "args.getLength() == 1"})
-    protected Object pMinMaxOneVecInt(@SuppressWarnings("unused") byte naRm, RArgsValuesAndNames args) {
+    protected Object pMinMaxOneVecInt(@SuppressWarnings("unused") boolean naRm, RArgsValuesAndNames args) {
         return args.getArgument(0);
     }
 
     @Specialization(guards = {"isIntegerPrecedence(args)", "args.getLength() > 1"})
-    protected RIntVector pMinMaxInt(byte naRm, RArgsValuesAndNames args) {
+    protected RIntVector pMinMaxInt(boolean naRm, RArgsValuesAndNames args) {
         int maxLength = convertToVectorAndEnableNACheck(args, getIntegerCastNode());
         if (lengthProfile.profile(maxLength == 0)) {
             return RDataFactory.createEmptyIntVector();
         } else {
-            boolean profiledNaRm = naRmProfile.profile(naRm == RRuntime.LOGICAL_TRUE);
+            boolean profiledNaRm = naRmProfile.profile(naRm);
             int[] data = new int[maxLength];
             Object[] argValues = args.getArguments();
             boolean warningAdded = false;
@@ -188,29 +200,29 @@ public abstract class PMinMax extends RBuiltinNode {
     }
 
     @Specialization(guards = {"isLogicalPrecedence(args)", "args.getLength() == 1"})
-    protected Object pMinMaxOneVecLogical(@SuppressWarnings("unused") byte naRm, RArgsValuesAndNames args) {
+    protected Object pMinMaxOneVecLogical(@SuppressWarnings("unused") boolean naRm, RArgsValuesAndNames args) {
         return args.getArgument(0);
     }
 
     @Specialization(guards = {"isLogicalPrecedence(args)", "args.getLength() != 1"})
-    protected RIntVector pMinMaxLogical(byte naRm, RArgsValuesAndNames args) {
+    protected RIntVector pMinMaxLogical(boolean naRm, RArgsValuesAndNames args) {
         return pMinMaxInt(naRm, args);
     }
 
     @Specialization(guards = {"isDoublePrecedence(args)", "args.getLength() == 0"})
     @SuppressWarnings("unused")
-    protected Object pMinMaxNoneVecDouble(byte naRm, RArgsValuesAndNames args) {
+    protected Object pMinMaxNoneVecDouble(boolean naRm, RArgsValuesAndNames args) {
         return RDataFactory.createEmptyDoubleVector();
     }
 
     @Specialization(guards = {"isDoublePrecedence(args)", "args.getLength() == 1"})
     @SuppressWarnings("unused")
-    protected Object pMinMaxOneVecDouble(byte naRm, RArgsValuesAndNames args) {
+    protected Object pMinMaxOneVecDouble(boolean naRm, RArgsValuesAndNames args) {
         return args.getArgument(0);
     }
 
     @Specialization(guards = {"isDoublePrecedence(args)", "args.getLength() ==2"})
-    protected RDoubleVector pMinMaxTwoDouble(byte naRm, RArgsValuesAndNames args, //
+    protected RDoubleVector pMinMaxTwoDouble(boolean naRm, RArgsValuesAndNames args, //
                     @Cached("create()") NACheck naCheckX, //
                     @Cached("create()") NACheck naCheckY, //
                     @Cached("create()") CastDoubleNode castX, //
@@ -231,7 +243,7 @@ public abstract class PMinMax extends RBuiltinNode {
             if ((xLength > 1 && xLength < maxLength) || (yLength > 1 && yLength < maxLength)) {
                 RError.warning(RError.SHOW_CALLER2, RError.Message.ARG_RECYCYLED);
             }
-            boolean profiledNaRm = naRmProfile.profile(naRm == RRuntime.LOGICAL_TRUE);
+            boolean profiledNaRm = naRmProfile.profile(naRm);
             double[] data = new double[maxLength];
             int xOffset = 0;
             int yOffset = 0;
@@ -259,7 +271,7 @@ public abstract class PMinMax extends RBuiltinNode {
     }
 
     @Specialization(guards = {"isDoublePrecedence(args)", "args.getLength() > 2"})
-    protected RDoubleVector pMinMaxDouble(byte naRm, RArgsValuesAndNames args) {
+    protected RDoubleVector pMinMaxDouble(boolean naRm, RArgsValuesAndNames args) {
         int maxLength = convertToVectorAndEnableNACheck(args, getDoubleCastNode());
         if (lengthProfile.profile(maxLength == 0)) {
             return RDataFactory.createEmptyDoubleVector();
@@ -274,7 +286,7 @@ public abstract class PMinMax extends RBuiltinNode {
                     warningAdded = true;
                 }
             }
-            boolean profiledNaRm = naRmProfile.profile(naRm == RRuntime.LOGICAL_TRUE);
+            boolean profiledNaRm = naRmProfile.profile(naRm);
             double[] data = new double[maxLength];
             for (int i = 0; i < maxLength; i++) {
                 double result = semantics.getDoubleStart();
@@ -300,17 +312,17 @@ public abstract class PMinMax extends RBuiltinNode {
 
     @Specialization(guards = {"isStringPrecedence(args)", "args.getLength() == 1"})
     @SuppressWarnings("unused")
-    protected Object pMinMaxOneVecString(byte naRm, RArgsValuesAndNames args) {
+    protected Object pMinMaxOneVecString(boolean naRm, RArgsValuesAndNames args) {
         return args.getArgument(0);
     }
 
     @Specialization(guards = {"isStringPrecedence(args)", "args.getLength() != 1"})
-    protected RStringVector pMinMaxString(byte naRm, RArgsValuesAndNames args) {
+    protected RStringVector pMinMaxString(boolean naRm, RArgsValuesAndNames args) {
         int maxLength = convertToVectorAndEnableNACheck(args, getStringCastNode());
         if (lengthProfile.profile(maxLength == 0)) {
             return RDataFactory.createEmptyStringVector();
         } else {
-            boolean profiledNaRm = naRmProfile.profile(naRm == RRuntime.LOGICAL_TRUE);
+            boolean profiledNaRm = naRmProfile.profile(naRm);
             String[] data = new String[maxLength];
             Object[] argValues = args.getArguments();
             byte warningAdded = RRuntime.LOGICAL_FALSE;
@@ -322,15 +334,9 @@ public abstract class PMinMax extends RBuiltinNode {
     }
 
     @SuppressWarnings("unused")
-    @Specialization(guards = "isComplexPrecedence(args)")
-    protected RComplexVector pMinMaxComplex(byte naRm, RArgsValuesAndNames args) {
-        throw RError.error(this, RError.Message.INVALID_INPUT_TYPE);
-    }
-
-    @SuppressWarnings("unused")
-    @Specialization(guards = "isRawPrecedence(args)")
-    protected RRawVector pMinMaxRaw(byte naRm, RArgsValuesAndNames args) {
-        throw RError.error(this, RError.Message.INVALID_INPUT_TYPE);
+    @Fallback
+    protected RRawVector pMinMaxRaw(Object naRm, RArgsValuesAndNames args) {
+        throw RError.error(NO_CALLER, RError.Message.INVALID_INPUT_TYPE);
     }
 
     @RBuiltin(name = "pmax", kind = INTERNAL, parameterNames = {"na.rm", "..."}, behavior = PURE)
@@ -367,14 +373,6 @@ public abstract class PMinMax extends RBuiltinNode {
         return precedence(args) == PrecedenceNode.STRING_PRECEDENCE;
     }
 
-    protected boolean isComplexPrecedence(RArgsValuesAndNames args) {
-        return precedence(args) == PrecedenceNode.COMPLEX_PRECEDENCE;
-    }
-
-    protected boolean isRawPrecedence(RArgsValuesAndNames args) {
-        return precedence(args) == PrecedenceNode.RAW_PRECEDENCE;
-    }
-
     private int precedence(RArgsValuesAndNames args) {
         int precedence = -1;
         Object[] array = args.getArguments();
@@ -386,7 +384,7 @@ public abstract class PMinMax extends RBuiltinNode {
 
     protected abstract static class MultiElemStringHandler extends RBaseNode {
 
-        public abstract byte executeByte(Object[] argValues, byte naRm, int offset, int ind, int maxLength, byte warning, Object data);
+        public abstract byte executeByte(Object[] argValues, boolean naRm, int offset, int ind, int maxLength, byte warning, Object data);
 
         @Child private MultiElemStringHandler recursiveStringHandler;
         private final ReduceSemantics semantics;
@@ -402,7 +400,7 @@ public abstract class PMinMax extends RBuiltinNode {
             this.na = na;
         }
 
-        private byte handleString(Object[] argValues, byte naRm, int offset, int ind, int maxLength, byte warning, Object data) {
+        private byte handleString(Object[] argValues, boolean naRm, int offset, int ind, int maxLength, byte warning, Object data) {
             if (recursiveStringHandler == null) {
                 CompilerDirectives.transferToInterpreterAndInvalidate();
                 recursiveStringHandler = insert(MultiElemStringHandlerNodeGen.create(semantics, factory, na));
@@ -411,7 +409,7 @@ public abstract class PMinMax extends RBuiltinNode {
         }
 
         @Specialization
-        protected byte doStringVectorMultiElem(Object[] argValues, byte naRm, int offset, int ind, int maxLength, byte warning, Object d) {
+        protected byte doStringVectorMultiElem(Object[] argValues, boolean naRm, int offset, int ind, int maxLength, byte warning, Object d) {
             String[] data = (String[]) d;
             byte warningAdded = warning;
             RAbstractStringVector vec = (RAbstractStringVector) argValues[offset];
@@ -421,7 +419,7 @@ public abstract class PMinMax extends RBuiltinNode {
             }
             String result = vec.getDataAt(ind % vec.getLength());
             na.enable(result);
-            if (naRmProfile.profile(naRm == RRuntime.LOGICAL_TRUE)) {
+            if (naRmProfile.profile(naRm)) {
                 if (na.check(result)) {
                     // the following is meant to eliminate leading NA-s
                     if (offset == argValues.length - 1) {
@@ -450,7 +448,7 @@ public abstract class PMinMax extends RBuiltinNode {
                 String current = vec.getDataAt(ind % vec.getLength());
                 na.enable(current);
                 if (na.check(current)) {
-                    if (naRmProfile.profile(naRm == RRuntime.LOGICAL_TRUE)) {
+                    if (naRmProfile.profile(naRm)) {
                         // skip NA-s
                         continue;
                     } else {
diff --git a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/Parse.java b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/Parse.java
index 10550c3ed5be05f2679fb47d7740b92f74fa5c80..38d27130321976f952690784f06faec2fc1f563d 100644
--- a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/Parse.java
+++ b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/Parse.java
@@ -22,24 +22,29 @@
  */
 package com.oracle.truffle.r.nodes.builtin.base;
 
+import static com.oracle.truffle.r.nodes.builtin.CastBuilder.Predef.asStringVector;
+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.nullValue;
+import static com.oracle.truffle.r.nodes.builtin.CastBuilder.Predef.stringValue;
+import static com.oracle.truffle.r.runtime.RError.Message.MUST_BE_STRING_OR_CONNECTION;
 import static com.oracle.truffle.r.runtime.builtins.RBehavior.IO;
 import static com.oracle.truffle.r.runtime.builtins.RBuiltinKind.INTERNAL;
 
 import java.io.File;
 import java.io.IOException;
+import java.net.URISyntaxException;
 
-import com.oracle.truffle.api.CompilerDirectives;
 import com.oracle.truffle.api.CompilerDirectives.TruffleBoundary;
 import com.oracle.truffle.api.dsl.Specialization;
 import com.oracle.truffle.api.source.Source;
 import com.oracle.truffle.api.source.SourceSection;
+import com.oracle.truffle.r.nodes.builtin.CastBuilder;
 import com.oracle.truffle.r.nodes.builtin.RBuiltinNode;
 import com.oracle.truffle.r.nodes.unary.CastIntegerNode;
-import com.oracle.truffle.r.nodes.unary.CastIntegerNodeGen;
 import com.oracle.truffle.r.nodes.unary.CastStringNode;
-import com.oracle.truffle.r.nodes.unary.CastStringNodeGen;
 import com.oracle.truffle.r.nodes.unary.CastToVectorNode;
-import com.oracle.truffle.r.nodes.unary.CastToVectorNodeGen;
 import com.oracle.truffle.r.runtime.RError;
 import com.oracle.truffle.r.runtime.RInternalError;
 import com.oracle.truffle.r.runtime.RRuntime;
@@ -50,14 +55,13 @@ import com.oracle.truffle.r.runtime.builtins.RBuiltin;
 import com.oracle.truffle.r.runtime.conn.ConnectionSupport;
 import com.oracle.truffle.r.runtime.conn.RConnection;
 import com.oracle.truffle.r.runtime.conn.StdConnections;
-import com.oracle.truffle.r.runtime.context.Engine.ParseException;
 import com.oracle.truffle.r.runtime.context.RContext;
+import com.oracle.truffle.r.runtime.context.Engine.ParseException;
 import com.oracle.truffle.r.runtime.data.RDataFactory;
 import com.oracle.truffle.r.runtime.data.RExpression;
 import com.oracle.truffle.r.runtime.data.RLanguage;
 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.RSymbol;
 import com.oracle.truffle.r.runtime.data.model.RAbstractStringVector;
 import com.oracle.truffle.r.runtime.env.REnvironment;
@@ -97,58 +101,38 @@ public abstract class Parse extends RBuiltinNode {
     @Child private CastStringNode castStringNode;
     @Child private CastToVectorNode castVectorNode;
 
-    private int castInt(Object n) {
-        if (castIntNode == null) {
-            CompilerDirectives.transferToInterpreterAndInvalidate();
-            castIntNode = insert(CastIntegerNodeGen.create(false, false, false));
-        }
-        int result = (int) castIntNode.executeInt(n);
-        if (RRuntime.isNA(result)) {
-            result = -1;
-        }
-        return result;
-    }
-
-    private RStringVector castString(Object s) {
-        if (castStringNode == null) {
-            CompilerDirectives.transferToInterpreterAndInvalidate();
-            castVectorNode = insert(CastToVectorNodeGen.create(false));
-            castStringNode = insert(CastStringNodeGen.create(false, false, false));
-        }
-        return (RStringVector) castStringNode.executeString(castVectorNode.execute(s));
+    @Override
+    protected void createCasts(CastBuilder casts) {
+        // Note: string is captured by the R wrapper and transformed to a file, other types not
+        casts.arg("conn").mustBe(RConnection.class, MUST_BE_STRING_OR_CONNECTION, "file");
+        casts.arg("n").asIntegerVector().findFirst(RRuntime.INT_NA).mapIf(RRuntime::isNA, constant(-1));
+        casts.arg("text").mapIf(nullValue().not(), chain(asStringVector()).with(findFirst().stringElement()).end());
+        casts.arg("prompt").asStringVector().findFirst("?");
+        casts.arg("encoding").mustBe(nullValue().not().and(stringValue())).asStringVector().findFirst();
     }
 
+    @TruffleBoundary
     @Specialization
-    protected Object parse(RConnection conn, Object n, Object text, RAbstractStringVector prompt, Object srcFile, RAbstractStringVector encoding) {
-        int nAsInt;
-        if (n != RNull.instance) {
-            nAsInt = castInt(n);
-        } else {
-            nAsInt = -1;
+    protected Object parse(RConnection conn, int n, RNull text, String prompt, Object srcFile, String encoding) {
+        String[] lines;
+        if (conn == StdConnections.getStdin()) {
+            throw RError.nyi(this, "parse from stdin not implemented");
         }
-        Object textVec = text;
-        if (textVec != RNull.instance) {
-            textVec = castString(textVec);
+        try (RConnection openConn = conn.forceOpen("r")) {
+            lines = openConn.readLines(0, false, false);
+        } catch (IOException ex) {
+            throw RError.error(this, RError.Message.PARSE_ERROR);
         }
-        return doParse(conn, nAsInt, textVec, prompt, srcFile, encoding);
+        return doParse(conn, n, lines, prompt, srcFile, encoding);
     }
 
     @TruffleBoundary
-    @SuppressWarnings("unused")
-    private Object doParse(RConnection conn, int n, Object textVec, RAbstractStringVector prompt, Object srcFile, RAbstractStringVector encoding) {
-        String[] lines;
-        if (textVec == RNull.instance) {
-            if (conn == StdConnections.getStdin()) {
-                throw RError.nyi(this, "parse from stdin not implemented");
-            }
-            try (RConnection openConn = conn.forceOpen("r")) {
-                lines = openConn.readLines(0, false, false);
-            } catch (IOException ex) {
-                throw RError.error(this, RError.Message.PARSE_ERROR);
-            }
-        } else {
-            lines = ((RStringVector) textVec).getDataWithoutCopying();
-        }
+    @Specialization
+    protected Object parse(RConnection conn, int n, RAbstractStringVector text, String prompt, Object srcFile, String encoding) {
+        return doParse(conn, n, text.materialize().getDataWithoutCopying(), prompt, srcFile, encoding);
+    }
+
+    private Object doParse(RConnection conn, int n, String[] lines, String prompt, Object srcFile, String encoding) {
         String coalescedLines = coalesce(lines);
         if (coalescedLines.length() == 0 || n == 0) {
             return RDataFactory.createExpression(RDataFactory.createList());
@@ -207,7 +191,9 @@ public abstract class Parse extends RBuiltinNode {
                 } else {
                     path = fileName;
                 }
-                return createFileSource(path, coalescedLines);
+                Source result = createFileSource(path, coalescedLines);
+                assert result != null : "Source created from environment should not be null";
+                return result;
             } else {
                 return Source.newBuilder(coalescedLines).name("<parse>").mimeType(RRuntime.R_APP_MIME).build();
             }
@@ -228,7 +214,12 @@ public abstract class Parse extends RBuiltinNode {
     }
 
     private static Source createFileSource(String path, String chars) {
-        return RSource.fromFileName(chars, path);
+        try {
+            return RSource.fromFileName(chars, path);
+        } catch (URISyntaxException e) {
+            // Note: to be compatible with GnuR we construct Source even with a malformed path
+            return Source.newBuilder(chars).name(path).mimeType(RRuntime.R_APP_MIME).build();
+        }
     }
 
     private static void addAttributes(RExpression exprs, Source source, REnvironment srcFile) {
diff --git a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/PathExpand.java b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/PathExpand.java
index d8ce346727888f085b67a939ac392c5af4aef715..af24c598864bfd084284228160ea702ecd45106c 100644
--- a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/PathExpand.java
+++ b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/PathExpand.java
@@ -22,13 +22,15 @@
  */
 package com.oracle.truffle.r.nodes.builtin.base;
 
+import static com.oracle.truffle.r.nodes.builtin.CastBuilder.Predef.nullValue;
+import static com.oracle.truffle.r.nodes.builtin.CastBuilder.Predef.stringValue;
 import static com.oracle.truffle.r.runtime.builtins.RBehavior.IO;
 import static com.oracle.truffle.r.runtime.builtins.RBuiltinKind.INTERNAL;
 
 import com.oracle.truffle.api.CompilerDirectives.TruffleBoundary;
 import com.oracle.truffle.api.dsl.Specialization;
+import com.oracle.truffle.r.nodes.builtin.CastBuilder;
 import com.oracle.truffle.r.nodes.builtin.RBuiltinNode;
-import com.oracle.truffle.r.runtime.RError;
 import com.oracle.truffle.r.runtime.Utils;
 import com.oracle.truffle.r.runtime.builtins.RBuiltin;
 import com.oracle.truffle.r.runtime.data.RDataFactory;
@@ -37,6 +39,11 @@ import com.oracle.truffle.r.runtime.data.model.RAbstractStringVector;
 @RBuiltin(name = "path.expand", kind = INTERNAL, parameterNames = "path", behavior = IO)
 public abstract class PathExpand extends RBuiltinNode {
 
+    @Override
+    protected void createCasts(CastBuilder casts) {
+        casts.arg("path").mustBe(nullValue().not().and(stringValue()));
+    }
+
     @Specialization
     @TruffleBoundary
     protected Object doPathExpand(RAbstractStringVector vec) {
@@ -47,10 +54,4 @@ public abstract class PathExpand extends RBuiltinNode {
         }
         return RDataFactory.createStringVector(results, RDataFactory.COMPLETE_VECTOR);
     }
-
-    @Specialization
-    @TruffleBoundary
-    protected Object doPathExpandGeneric(@SuppressWarnings("unused") Object path) {
-        throw RError.error(this, RError.Message.INVALID_ARGUMENT, "path");
-    }
 }
diff --git a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/RNGFunctions.java b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/RNGFunctions.java
index 8c7c8ca2f7e10e958b0ea21955b58b896630a6ea..e37be4dadf0d12bc2f96da400b32bfc3eb894bc9 100644
--- a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/RNGFunctions.java
+++ b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/RNGFunctions.java
@@ -22,53 +22,58 @@
  */
 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.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.nullValue;
+import static com.oracle.truffle.r.nodes.builtin.CastBuilder.Predef.numericValue;
+import static com.oracle.truffle.r.nodes.builtin.CastBuilder.Predef.stringValue;
+import static com.oracle.truffle.r.runtime.RError.SHOW_CALLER;
+import static com.oracle.truffle.r.runtime.RError.Message.INVALID_ARGUMENT;
+import static com.oracle.truffle.r.runtime.RError.Message.INVALID_NORMAL_TYPE_IN_RGNKIND;
+import static com.oracle.truffle.r.runtime.RError.Message.SEED_NOT_VALID_INT;
+import static com.oracle.truffle.r.runtime.RError.Message.UNIMPLEMENTED_TYPE_IN_FUNCTION;
 import static com.oracle.truffle.r.runtime.RVisibility.OFF;
 import static com.oracle.truffle.r.runtime.builtins.RBehavior.MODIFIES_STATE;
 import static com.oracle.truffle.r.runtime.builtins.RBuiltinKind.INTERNAL;
 
-import com.oracle.truffle.api.CompilerDirectives;
 import com.oracle.truffle.api.dsl.Specialization;
+import com.oracle.truffle.r.nodes.builtin.CastBuilder;
 import com.oracle.truffle.r.nodes.builtin.RBuiltinNode;
-import com.oracle.truffle.r.runtime.RError;
+import com.oracle.truffle.r.runtime.RError.Message;
 import com.oracle.truffle.r.runtime.builtins.RBuiltin;
 import com.oracle.truffle.r.runtime.data.RDataFactory;
 import com.oracle.truffle.r.runtime.data.RIntVector;
 import com.oracle.truffle.r.runtime.data.RNull;
-import com.oracle.truffle.r.runtime.data.model.RAbstractIntVector;
 import com.oracle.truffle.r.runtime.rng.RRNG;
 
 public class RNGFunctions {
     @RBuiltin(name = "set.seed", visibility = OFF, kind = INTERNAL, parameterNames = {"seed", "kind", "normal.kind"}, behavior = MODIFIES_STATE)
     public abstract static class SetSeed extends RBuiltinNode {
 
-        @SuppressWarnings("unused")
-        @Specialization
-        protected RNull setSeed(double seed, RNull kind, RNull normKind) {
-            doSetSeed((int) seed, RRNG.NO_KIND_CHANGE, RRNG.NO_KIND_CHANGE);
-            return RNull.instance;
+        @Override
+        protected void createCasts(CastBuilder casts) {
+            casts.arg("seed").mustBe(numericValue().or(nullValue()), SHOW_CALLER, SEED_NOT_VALID_INT).mapIf(nullValue().not(), chain(asIntegerVector()).with(findFirst().stringElement()).end());
+            Casts.kindInteger(casts, "kind", INVALID_ARGUMENT, "kind");
+            // TODO: implement normal.kind specializations with String
+            casts.arg("normal.kind").mustBe(stringValue().or(nullValue()), SHOW_CALLER, INVALID_NORMAL_TYPE_IN_RGNKIND).mustBe(nullValue(), UNIMPLEMENTED_TYPE_IN_FUNCTION, "String", "set.seed");
         }
 
         @SuppressWarnings("unused")
         @Specialization
-        protected RNull setSeed(double seed, RAbstractIntVector kind, RNull normKind) {
-            doSetSeed((int) seed, kind.getDataAt(0), RRNG.NO_KIND_CHANGE);
+        protected RNull setSeed(int seed, int kind, RNull normKind) {
+            doSetSeed(seed, kind, RRNG.NO_KIND_CHANGE);
             return RNull.instance;
         }
 
         @SuppressWarnings("unused")
         @Specialization
-        protected RNull setSeed(RNull seed, RNull kind, RNull normKind) {
-            doSetSeed(RRNG.timeToSeed(), RRNG.NO_KIND_CHANGE, RRNG.NO_KIND_CHANGE);
+        protected RNull setSeed(RNull seed, int kind, RNull normKind) {
+            doSetSeed(RRNG.timeToSeed(), kind, RRNG.NO_KIND_CHANGE);
             return RNull.instance;
         }
 
-        @SuppressWarnings("unused")
-        @Specialization
-        protected RNull setSeed(byte seed, RNull kind, RNull normKind) {
-            CompilerDirectives.transferToInterpreter();
-            throw RError.error(this, RError.Message.SEED_NOT_VALID_INT);
-        }
-
         private static void doSetSeed(int newSeed, int kind, int normKind) {
             RRNG.doSetSeed(newSeed, kind, normKind);
         }
@@ -77,25 +82,30 @@ public class RNGFunctions {
     @RBuiltin(name = "RNGkind", kind = INTERNAL, parameterNames = {"kind", "normkind"}, behavior = MODIFIES_STATE)
     public abstract static class RNGkind extends RBuiltinNode {
 
+        @Override
+        protected void createCasts(CastBuilder casts) {
+            Casts.kindInteger(casts, "kind", INVALID_ARGUMENT, "kind");
+            Casts.kindInteger(casts, "normkind", INVALID_NORMAL_TYPE_IN_RGNKIND);
+        }
+
         @Specialization
-        protected RIntVector doRNGkind(Object kind, Object normKind) {
+        protected RIntVector doRNGkind(int kind, int normKind) {
             RRNG.getRNGState();
             RIntVector result = getCurrent();
-            int kindChange = checkType(kind, "kind");
-            int normKindChange = checkType(normKind, "normkind");
-            RRNG.doRNGKind(kindChange, normKindChange);
+            RRNG.doRNGKind(kind, normKind);
             return result;
         }
 
-        private int checkType(Object kind, String name) {
-            if (!(kind == RNull.instance || kind instanceof RIntVector || kind instanceof Integer)) {
-                throw RError.error(this, RError.Message.INVALID_ARGUMENT, name);
-            }
-            return kind == RNull.instance ? RRNG.NO_KIND_CHANGE : kind instanceof Integer ? (Integer) kind : ((RAbstractIntVector) kind).getDataAt(0);
-        }
-
         private static RIntVector getCurrent() {
             return RDataFactory.createIntVector(new int[]{RRNG.currentKindAsInt(), RRNG.currentNormKindAsInt()}, RDataFactory.COMPLETE_VECTOR);
         }
     }
+
+    private static final class Casts {
+        public static void kindInteger(CastBuilder casts, String name, Message error, Object... messageArgs) {
+            casts.arg(name).mustBe(nullValue().or(numericValue()), SHOW_CALLER, error, messageArgs).mapIf(nullValue().not(), chain(asIntegerVector()).with(findFirst().stringElement()).end()).mapIf(
+                            nullValue(),
+                            constant(RRNG.NO_KIND_CHANGE));
+        }
+    }
 }
diff --git a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/Rank.java b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/Rank.java
index 808450ebf3bd2d4012d71e35239fd801358bafde..022d7ec2dc439847dbfe06cf2863815e5f045b67 100644
--- a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/Rank.java
+++ b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/Rank.java
@@ -12,23 +12,36 @@
  */
 package com.oracle.truffle.r.nodes.builtin.base;
 
+import static com.oracle.truffle.r.nodes.builtin.CastBuilder.Predef.abstractVectorValue;
+import static com.oracle.truffle.r.nodes.builtin.CastBuilder.Predef.gte0;
+import static com.oracle.truffle.r.nodes.builtin.CastBuilder.Predef.intNA;
+import static com.oracle.truffle.r.nodes.builtin.CastBuilder.Predef.notEmpty;
+import static com.oracle.truffle.r.nodes.builtin.CastBuilder.Predef.numericValue;
+import static com.oracle.truffle.r.nodes.builtin.CastBuilder.Predef.rawValue;
+import static com.oracle.truffle.r.nodes.builtin.CastBuilder.Predef.stringValue;
+import static com.oracle.truffle.r.runtime.RError.NO_CALLER;
+import static com.oracle.truffle.r.runtime.RError.SHOW_CALLER;
+import static com.oracle.truffle.r.runtime.RError.Message.INVALID_TIES_FOR_RANK;
+import static com.oracle.truffle.r.runtime.RError.Message.INVALID_VALUE;
+import static com.oracle.truffle.r.runtime.RError.Message.RANK_LARGE_N;
+import static com.oracle.truffle.r.runtime.RError.Message.UNIMPLEMENTED_TYPE_IN_GREATER;
 import static com.oracle.truffle.r.runtime.builtins.RBehavior.PURE;
 import static com.oracle.truffle.r.runtime.builtins.RBuiltinKind.INTERNAL;
 
+import java.util.function.Function;
+
 import com.oracle.truffle.api.dsl.Specialization;
+import com.oracle.truffle.api.profiles.BranchProfile;
 import com.oracle.truffle.r.nodes.builtin.CastBuilder;
 import com.oracle.truffle.r.nodes.builtin.RBuiltinNode;
 import com.oracle.truffle.r.nodes.builtin.base.OrderNodeGen.CmpNodeGen;
 import com.oracle.truffle.r.nodes.builtin.base.OrderNodeGen.OrderVector1NodeGen;
 import com.oracle.truffle.r.runtime.RError;
-import com.oracle.truffle.r.runtime.RRuntime;
 import com.oracle.truffle.r.runtime.builtins.RBuiltin;
 import com.oracle.truffle.r.runtime.data.RDataFactory;
 import com.oracle.truffle.r.runtime.data.RIntVector;
-import com.oracle.truffle.r.runtime.data.RRawVector;
 import com.oracle.truffle.r.runtime.data.closures.RClosures;
 import com.oracle.truffle.r.runtime.data.model.RAbstractLogicalVector;
-import com.oracle.truffle.r.runtime.data.model.RAbstractStringVector;
 import com.oracle.truffle.r.runtime.data.model.RAbstractVector;
 
 @RBuiltin(name = "rank", kind = INTERNAL, parameterNames = {"x", "len", "ties.method"}, behavior = PURE)
@@ -36,18 +49,31 @@ public abstract class Rank extends RBuiltinNode {
 
     @Child private Order.OrderVector1Node orderVector1Node;
     @Child private Order.CmpNode orderCmpNode;
+    private final BranchProfile errorProfile = BranchProfile.create();
 
     private static final Object rho = new Object();
 
     private enum TiesKind {
         AVERAGE,
         MAX,
-        MIN;
+        MIN
     }
 
     @Override
     protected void createCasts(CastBuilder casts) {
-        casts.toInteger(1);
+        // @formatter:off
+        Function<Object, Object> typeFunc = x -> x.getClass().getSimpleName();
+        casts.arg("x").mustBe(abstractVectorValue(), SHOW_CALLER, UNIMPLEMENTED_TYPE_IN_GREATER, typeFunc).
+                mustBe(rawValue().not(), SHOW_CALLER, RError.Message.RAW_SORT);
+        // Note: in the case of no long vector support, when given anything but integer as n, GnuR behaves as if n=1,
+        // we allow ourselves to be bit inconsistent with GnuR in that.
+        casts.arg("len").defaultError(NO_CALLER, INVALID_VALUE, "length(xx)").mustBe(numericValue()).
+                asIntegerVector().
+                mustBe(notEmpty()).
+                findFirst().mustBe(intNA().not().and(gte0()));
+        // Note: we parse ties.methods in the Specialization anyway, so the validation of the value is there
+        casts.arg("ties.method").defaultError(NO_CALLER, INVALID_TIES_FOR_RANK).mustBe(stringValue()).asStringVector().findFirst();
+        // @formatter:on
     }
 
     private Order.OrderVector1Node initOrderVector1() {
@@ -65,30 +91,15 @@ public abstract class Rank extends RBuiltinNode {
     }
 
     @Specialization
-    protected Object rank(RAbstractVector xa, int n, RAbstractStringVector tiesMethod) {
-        if (n < 0 || RRuntime.isNA(n)) {
-            throw RError.error(this, RError.Message.INVALID_ARGUMENT, "length(xx)");
-        }
-        if (xa instanceof RRawVector) {
-            throw RError.error(this, RError.Message.RAW_SORT);
+    protected Object rank(RAbstractVector xa, int inN, String tiesMethod) {
+        int n = inN;
+        if (n > xa.getLength()) {
+            errorProfile.enter();
+            n = xa.getLength();
+            RError.warning(SHOW_CALLER, RANK_LARGE_N);
         }
-        TiesKind tiesKind;
-        switch (tiesMethod.getDataAt(0)) {
-            case "average":
-                tiesKind = TiesKind.AVERAGE;
-                break;
-
-            case "max":
-                tiesKind = TiesKind.MAX;
-                break;
-
-            case "min":
-                tiesKind = TiesKind.MIN;
-                break;
-            default:
-                throw RError.error(this, RError.Message.GENERIC, "invalid ties.method for rank() [should never happen]");
 
-        }
+        TiesKind tiesKind = getTiesKind(tiesMethod);
         int[] ik = null;
         double[] rk = null;
         if (tiesKind == TiesKind.AVERAGE) {
@@ -134,4 +145,18 @@ public abstract class Rank extends RBuiltinNode {
             return RDataFactory.createIntVector(ik, RDataFactory.COMPLETE_VECTOR);
         }
     }
+
+    private TiesKind getTiesKind(String tiesMethod) {
+        switch (tiesMethod) {
+            case "average":
+                return TiesKind.AVERAGE;
+            case "max":
+                return TiesKind.MAX;
+            case "min":
+                return TiesKind.MIN;
+            default:
+                errorProfile.enter();
+                throw RError.error(NO_CALLER, RError.Message.GENERIC, "invalid ties.method for rank() [should never happen]");
+        }
+    }
 }
diff --git a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/Rm.java b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/Rm.java
index 1179ceb44c580aa2af3a8a36cc0441b7e695e79b..424332d735ac91a2cf4f20a1094af721f162d1f8 100644
--- a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/Rm.java
+++ b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/Rm.java
@@ -22,6 +22,14 @@
  */
 package com.oracle.truffle.r.nodes.builtin.base;
 
+import static com.oracle.truffle.r.nodes.builtin.CastBuilder.Predef.nullValue;
+import static com.oracle.truffle.r.nodes.builtin.CastBuilder.Predef.numericValue;
+import static com.oracle.truffle.r.nodes.builtin.CastBuilder.Predef.stringValue;
+import static com.oracle.truffle.r.nodes.builtin.CastBuilder.Predef.toBoolean;
+import static com.oracle.truffle.r.runtime.RError.SHOW_CALLER;
+import static com.oracle.truffle.r.runtime.RError.Message.INVALID_ARGUMENT;
+import static com.oracle.truffle.r.runtime.RError.Message.INVALID_FIRST_ARGUMENT;
+import static com.oracle.truffle.r.runtime.RError.Message.USE_NULL_ENV_DEFUNCT;
 import static com.oracle.truffle.r.runtime.RVisibility.OFF;
 import static com.oracle.truffle.r.runtime.builtins.RBehavior.COMPLEX;
 import static com.oracle.truffle.r.runtime.builtins.RBuiltinKind.INTERNAL;
@@ -32,6 +40,7 @@ import com.oracle.truffle.api.frame.Frame;
 import com.oracle.truffle.api.frame.FrameSlot;
 import com.oracle.truffle.api.frame.VirtualFrame;
 import com.oracle.truffle.api.profiles.BranchProfile;
+import com.oracle.truffle.r.nodes.builtin.CastBuilder;
 import com.oracle.truffle.r.nodes.builtin.RBuiltinNode;
 import com.oracle.truffle.r.runtime.RArguments;
 import com.oracle.truffle.r.runtime.RError;
@@ -43,15 +52,26 @@ import com.oracle.truffle.r.runtime.env.REnvironment;
 import com.oracle.truffle.r.runtime.env.REnvironment.PutException;
 import com.oracle.truffle.r.runtime.env.frame.FrameSlotChangeMonitor;
 
+/**
+ * Note: remove is invoked from builtin wrappers 'rm' and 'remove' that are identical.
+ */
 @RBuiltin(name = "remove", visibility = OFF, kind = INTERNAL, parameterNames = {"list", "envir", "inherits"}, behavior = COMPLEX)
 public abstract class Rm extends RBuiltinNode {
 
     private final BranchProfile invalidateProfile = BranchProfile.create();
 
+    @Override
+    protected void createCasts(CastBuilder casts) {
+        casts.arg("list").mustBe(stringValue(), SHOW_CALLER, INVALID_FIRST_ARGUMENT);
+        casts.arg("envir").mustBe(nullValue().not(), SHOW_CALLER, USE_NULL_ENV_DEFUNCT).mustBe(REnvironment.class, SHOW_CALLER, INVALID_ARGUMENT, "envir");
+        casts.arg("inherits").mustBe(numericValue(), SHOW_CALLER, INVALID_ARGUMENT, "inherits").asLogicalVector().findFirst().map(toBoolean());
+    }
+
     // this specialization is for internal use only
+    // TODO: what internal use? Does it still apply?
     @Specialization
     @SuppressWarnings("unused")
-    protected Object rm(VirtualFrame frame, String name, RMissing envir, byte inherits) {
+    protected Object rm(VirtualFrame frame, String name, RMissing envir, boolean inherits) {
         removeFromFrame(frame, name);
         return RNull.instance;
     }
@@ -59,7 +79,7 @@ public abstract class Rm extends RBuiltinNode {
     @Specialization
     @TruffleBoundary
     @SuppressWarnings("unused")
-    protected Object rm(RAbstractStringVector list, REnvironment envir, byte inherits) {
+    protected Object rm(RAbstractStringVector list, REnvironment envir, boolean inherits) {
         try {
             for (int i = 0; i < list.getLength(); i++) {
                 if (envir == REnvironment.globalEnv()) {
@@ -69,7 +89,7 @@ public abstract class Rm extends RBuiltinNode {
                 }
             }
         } catch (PutException ex) {
-            throw RError.error(RError.SHOW_CALLER, ex);
+            throw RError.error(SHOW_CALLER, ex);
         }
         return RNull.instance;
     }
@@ -85,7 +105,7 @@ public abstract class Rm extends RBuiltinNode {
             }
         }
         if (fs == null) {
-            RError.warning(RError.SHOW_CALLER, RError.Message.UNKNOWN_OBJECT, x);
+            RError.warning(SHOW_CALLER, RError.Message.UNKNOWN_OBJECT, x);
         } else {
             // use null (not an R value) to represent "undefined"
             FrameSlotChangeMonitor.setObjectAndInvalidate(frame, fs, null, false, invalidateProfile);
diff --git a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/Row.java b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/Row.java
index 7f03a651e9dd5bde1f756f1c6053939b21d08997..a2504949798a07cff7305cb4cf8bad029b9f7329 100644
--- a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/Row.java
+++ b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/Row.java
@@ -12,22 +12,30 @@
  */
 package com.oracle.truffle.r.nodes.builtin.base;
 
+import static com.oracle.truffle.r.nodes.builtin.CastBuilder.Predef.integerValue;
+import static com.oracle.truffle.r.nodes.builtin.CastBuilder.Predef.nullValue;
+import static com.oracle.truffle.r.nodes.builtin.CastBuilder.Predef.size;
+import static com.oracle.truffle.r.runtime.RError.SHOW_CALLER;
 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.CompilerDirectives.TruffleBoundary;
 import com.oracle.truffle.api.dsl.Specialization;
+import com.oracle.truffle.r.nodes.builtin.CastBuilder;
 import com.oracle.truffle.r.nodes.builtin.RBuiltinNode;
 import com.oracle.truffle.r.runtime.RError;
 import com.oracle.truffle.r.runtime.builtins.RBuiltin;
 import com.oracle.truffle.r.runtime.data.RDataFactory;
 import com.oracle.truffle.r.runtime.data.RIntVector;
-import com.oracle.truffle.r.runtime.data.RNull;
 import com.oracle.truffle.r.runtime.data.model.RAbstractIntVector;
 
 @RBuiltin(name = "row", kind = INTERNAL, parameterNames = {"dims"}, behavior = PURE)
 public abstract class Row extends RBuiltinNode {
 
+    @Override
+    protected void createCasts(CastBuilder casts) {
+        casts.arg("dims").mustBe(nullValue().not().and(integerValue()), SHOW_CALLER, RError.Message.MATRIX_LIKE_REQUIRED, "row").asIntegerVector().mustBe(size(2));
+    }
+
     @Specialization
     protected RIntVector col(RAbstractIntVector x) {
         int nrows = x.getDataAt(0);
@@ -40,10 +48,4 @@ public abstract class Row extends RBuiltinNode {
         }
         return RDataFactory.createIntVector(result, RDataFactory.COMPLETE_VECTOR, new int[]{nrows, ncols});
     }
-
-    @Specialization
-    @TruffleBoundary
-    protected RIntVector col(@SuppressWarnings("unused") RNull x) {
-        throw RError.error(this, RError.Message.MATRIX_LIKE_REQUIRED, "row");
-    }
 }
diff --git a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/RowMeans.java b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/RowMeans.java
index 5d97a4dac5811ed73dcbaa0fb2723ae96f6ad00a..ca940f61df65a057af3aad080c4776d761f8a624 100644
--- a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/RowMeans.java
+++ b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/RowMeans.java
@@ -10,23 +10,23 @@
  */
 package com.oracle.truffle.r.nodes.builtin.base;
 
+import static com.oracle.truffle.r.nodes.builtin.CastBuilder.Predef.numericValue;
 import static com.oracle.truffle.r.nodes.builtin.CastBuilder.Predef.toBoolean;
+import static com.oracle.truffle.r.runtime.RError.SHOW_CALLER;
+import static com.oracle.truffle.r.runtime.RError.Message.X_NUMERIC;
 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.CompilerDirectives;
 import com.oracle.truffle.api.CompilerDirectives.TruffleBoundary;
 import com.oracle.truffle.api.dsl.Specialization;
 import com.oracle.truffle.r.nodes.builtin.CastBuilder;
 import com.oracle.truffle.r.nodes.builtin.RBuiltinNode;
-import com.oracle.truffle.r.runtime.RError;
 import com.oracle.truffle.r.runtime.RRuntime;
 import com.oracle.truffle.r.runtime.builtins.RBuiltin;
 import com.oracle.truffle.r.runtime.data.RDataFactory;
 import com.oracle.truffle.r.runtime.data.RDoubleVector;
 import com.oracle.truffle.r.runtime.data.RIntVector;
 import com.oracle.truffle.r.runtime.data.RLogicalVector;
-import com.oracle.truffle.r.runtime.data.model.RAbstractStringVector;
 import com.oracle.truffle.r.runtime.ops.BinaryArithmetic;
 import com.oracle.truffle.r.runtime.ops.na.NACheck;
 
@@ -39,6 +39,8 @@ public abstract class RowMeans extends RBuiltinNode {
 
     @Override
     protected void createCasts(CastBuilder casts) {
+        casts.arg("X").mustBe(numericValue(), SHOW_CALLER, X_NUMERIC);
+
         casts.arg("m").asIntegerVector().findFirst().notNA();
 
         casts.arg("n").asIntegerVector().findFirst().notNA();
@@ -189,12 +191,4 @@ public abstract class RowMeans extends RBuiltinNode {
         }
         return RDataFactory.createDoubleVector(result, isComplete);
     }
-
-    @SuppressWarnings("unused")
-    @Specialization
-    protected RDoubleVector rowMeans(RAbstractStringVector x, int rowNum, int colNum, boolean naRm) {
-        CompilerDirectives.transferToInterpreter();
-        throw RError.error(this, RError.Message.X_NUMERIC);
-    }
-
 }
diff --git a/com.oracle.truffle.r.nodes.test/src/com/oracle/truffle/r/nodes/casts/PredefMappersSamplers.java b/com.oracle.truffle.r.nodes.test/src/com/oracle/truffle/r/nodes/casts/PredefMappersSamplers.java
index f69fe0e8fed66d1f304fa673968f7a186cc67ce7..7f52b7c1b07f2cf5222d484de6b8d61c19559cb9 100644
--- a/com.oracle.truffle.r.nodes.test/src/com/oracle/truffle/r/nodes/casts/PredefMappersSamplers.java
+++ b/com.oracle.truffle.r.nodes.test/src/com/oracle/truffle/r/nodes/casts/PredefMappersSamplers.java
@@ -72,28 +72,29 @@ public final class PredefMappersSamplers implements PredefMappers {
 
     @Override
     public <T> ValuePredicateArgumentMapperSampler<T, RNull> nullConstant() {
-        return ValuePredicateArgumentMapperSampler.<T, RNull> fromLambda((T x) -> RNull.instance, null, null, RNull.class);
+        return ValuePredicateArgumentMapperSampler.fromLambda((T x) -> RNull.instance, null, null, RNull.class);
     }
 
     @Override
-    public ValuePredicateArgumentMapperSampler<String, String> constant(String s) {
-        return ValuePredicateArgumentMapperSampler.<String, String> fromLambda((String x) -> s, (String x) -> s, CastUtils.<String> samples(), CastUtils.<String> samples(), String.class,
+    public <T> ValuePredicateArgumentMapperSampler<T, String> constant(String s) {
+        return ValuePredicateArgumentMapperSampler.fromLambda((T x) -> s, (String x) -> null, CastUtils.<T> samples(), CastUtils.<T> samples(), null,
                         String.class);
     }
 
     @Override
-    public ValuePredicateArgumentMapperSampler<Integer, Integer> constant(int i) {
-        return ValuePredicateArgumentMapperSampler.fromLambda(x -> i, x -> i, CastUtils.<Integer> samples(), CastUtils.<Integer> samples(), Integer.class, Integer.class);
+    public <T> ValuePredicateArgumentMapperSampler<T, Integer> constant(int i) {
+        return ValuePredicateArgumentMapperSampler.fromLambda((T x) -> i, (Integer x) -> null, CastUtils.<T> samples(), CastUtils.<T> samples(), null,
+                        Integer.class);
     }
 
     @Override
-    public ValuePredicateArgumentMapperSampler<Double, Double> constant(double d) {
-        return ValuePredicateArgumentMapperSampler.fromLambda(x -> d, x -> d, CastUtils.<Double> samples(), CastUtils.<Double> samples(), Double.class, Double.class);
+    public <T> ValuePredicateArgumentMapperSampler<T, Double> constant(double d) {
+        return ValuePredicateArgumentMapperSampler.fromLambda((T x) -> d, (Double x) -> null, CastUtils.<T> samples(), CastUtils.<T> samples(), null, Double.class);
     }
 
     @Override
-    public ValuePredicateArgumentMapperSampler<Byte, Byte> constant(byte l) {
-        return ValuePredicateArgumentMapperSampler.fromLambda(x -> l, x -> l, CastUtils.<Byte> samples(), CastUtils.<Byte> samples(), Byte.class, Byte.class);
+    public <T> ValuePredicateArgumentMapperSampler<T, Byte> constant(byte l) {
+        return ValuePredicateArgumentMapperSampler.fromLambda((T x) -> l, x -> null, CastUtils.<T> samples(), CastUtils.<T> samples(), null, Byte.class);
     }
 
     @Override
diff --git a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/builtin/CastBuilder.java b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/builtin/CastBuilder.java
index bdb3ab24013c8d7845227ce226f27db41e0b49b5..499bba1f948ea3719ae8b6deed74ff27070981fb 100644
--- a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/builtin/CastBuilder.java
+++ b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/builtin/CastBuilder.java
@@ -335,13 +335,13 @@ public final class CastBuilder {
 
         <T> ValuePredicateArgumentMapper<T, RNull> nullConstant();
 
-        ValuePredicateArgumentMapper<String, String> constant(String s);
+        <T> ValuePredicateArgumentMapper<T, String> constant(String s);
 
-        ValuePredicateArgumentMapper<Integer, Integer> constant(int i);
+        <T> ValuePredicateArgumentMapper<T, Integer> constant(int i);
 
-        ValuePredicateArgumentMapper<Double, Double> constant(double d);
+        <T> ValuePredicateArgumentMapper<T, Double> constant(double d);
 
-        ValuePredicateArgumentMapper<Byte, Byte> constant(byte l);
+        <T> ValuePredicateArgumentMapper<T, Byte> constant(byte l);
 
         <T> ArgumentMapper<T, T> defaultValue(T defVal);
 
@@ -646,22 +646,22 @@ public final class CastBuilder {
         }
 
         @Override
-        public ValuePredicateArgumentMapper<String, String> constant(String s) {
-            return ValuePredicateArgumentMapper.<String, String> fromLambda((String x) -> s);
+        public <T> ValuePredicateArgumentMapper<T, String> constant(String s) {
+            return ValuePredicateArgumentMapper.fromLambda((T x) -> s);
         }
 
         @Override
-        public ValuePredicateArgumentMapper<Integer, Integer> constant(int i) {
+        public <T> ValuePredicateArgumentMapper<T, Integer> constant(int i) {
             return ValuePredicateArgumentMapper.fromLambda(x -> i);
         }
 
         @Override
-        public ValuePredicateArgumentMapper<Double, Double> constant(double d) {
+        public <T> ValuePredicateArgumentMapper<T, Double> constant(double d) {
             return ValuePredicateArgumentMapper.fromLambda(x -> d);
         }
 
         @Override
-        public ValuePredicateArgumentMapper<Byte, Byte> constant(byte l) {
+        public <T> ValuePredicateArgumentMapper<T, Byte> constant(byte l) {
             return ValuePredicateArgumentMapper.fromLambda(x -> l);
         }
 
@@ -1154,19 +1154,19 @@ public final class CastBuilder {
             return predefMappers().nullConstant();
         }
 
-        public static ValuePredicateArgumentMapper<String, String> constant(String s) {
+        public static <T> ValuePredicateArgumentMapper<T, String> constant(String s) {
             return predefMappers().constant(s);
         }
 
-        public static ValuePredicateArgumentMapper<Integer, Integer> constant(int i) {
+        public static <T> ValuePredicateArgumentMapper<T, Integer> constant(int i) {
             return predefMappers().constant(i);
         }
 
-        public static ValuePredicateArgumentMapper<Double, Double> constant(double d) {
+        public static <T> ValuePredicateArgumentMapper<T, Double> constant(double d) {
             return predefMappers().constant(d);
         }
 
-        public static ValuePredicateArgumentMapper<Byte, Byte> constant(byte l) {
+        public static <T> ValuePredicateArgumentMapper<T, Byte> constant(byte l) {
             return predefMappers().constant(l);
         }
 
@@ -1607,6 +1607,7 @@ public final class CastBuilder {
          * no warning message.
          */
         default HeadPhaseBuilder<S> findFirst(S defaultValue) {
+            assert defaultValue != null : "defaultValue cannot be null";
             state().castBuilder().insert(state().index(), FindFirstNodeGen.create(elementClass(), defaultValue));
             return state().factory.newHeadPhaseBuilder(this);
         }
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 d74e744ac7be3056d90b74d29b452c0fe63245d3..692e68ad39787190beaab5d76c4882d28ec14ca8 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
@@ -318,6 +318,7 @@ public final class RError extends RuntimeException {
         ONLY_WRITE_BINARY_CONNECTION("can only write to a binary connection"),
         NOT_A_TEXT_CONNECTION("'con' is not a textConnection"),
         UNSEEKABLE_CONNECTION("'con' is not seekable"),
+        MUST_BE_STRING_OR_CONNECTION("'%s' must be a character string or a connection"),
         MORE_CHARACTERS("more characters requested than are in the string - will zero-pad"),
         TOO_FEW_LINES_READ_LINES("too few lines read in readLineWRITE_ONs"),
         INVALID_CONNECTION("invalid connection"),
@@ -475,6 +476,7 @@ public final class RError extends RuntimeException {
         EXACT_SINGULARITY("exact singularity in '%s'"),
         SINGULAR_SOLVE("singular matrix '%s' in solve"),
         SEED_TYPE(".Random.seed is not an integer vector but of type '%s'"),
+        INVALID_NORMAL_TYPE_IN_RGNKIND("invalid Normal type in 'RNGkind'"),
         INVALID_USE("invalid use of '%s'"),
         FORMAL_MATCHED_MULTIPLE("formal argument \"%s\" matched by multiple actual arguments"),
         ARGUMENT_MATCHES_MULTIPLE("argument %d matches multiple formal arguments"),
@@ -508,6 +510,9 @@ public final class RError extends RuntimeException {
         MUST_BE_ONE_BYTE("invalid %s: must be one byte"),
         INVALID_DECIMAL_SEP("invalid decimal separator"),
         INVALID_QUOTE_SYMBOL("invalid quote symbol set"),
+        INVALID_TIES_FOR_RANK("invalid ties.method for rank() [should never happen]"),
+        UNIMPLEMENTED_TYPE_IN_GREATER("unimplemented type '%s' in greater"),
+        RANK_LARGE_N("parameter 'n' is greater than length(x), GnuR output is non-deterministic, FastR will use n=length(x)"),
         // below: not exactly GNU-R message
         TOO_FEW_POSITIVE_PROBABILITY("too few positive probabilities"),
         DOTS_BOUNDS("The ... list does not contain %s elements"),
diff --git a/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/RSource.java b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/RSource.java
index 29ebcd0c94c992a08fc2e6a3b616eb2e6b9c140a..d02be78943a02cc152563c7394bd78b1fd7fb80f 100644
--- a/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/RSource.java
+++ b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/RSource.java
@@ -88,14 +88,10 @@ public class RSource {
      * Create an (external) source from the {@code text} that is known to originate from the file
      * system path {@code path}. The simulates the behavior of {@link #fromFile}.
      */
-    public static Source fromFileName(String text, String path) {
+    public static Source fromFileName(String text, String path) throws URISyntaxException {
         File file = new File(path).getAbsoluteFile();
-        try {
-            URI uri = new URI("file://" + file.getAbsolutePath());
-            return Source.newBuilder(text).name(file.getName()).uri(uri).mimeType(RRuntime.R_APP_MIME).build();
-        } catch (URISyntaxException ex) {
-            throw RInternalError.shouldNotReachHere(ex);
-        }
+        URI uri = new URI("file://" + file.getAbsolutePath());
+        return Source.newBuilder(text).name(file.getName()).uri(uri).mimeType(RRuntime.R_APP_MIME).build();
     }
 
     /**
diff --git a/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/rng/RRNG.java b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/rng/RRNG.java
index 3a6e356fcfaeb38539cacd10aeade9d1bf823d61..e612d30596a030b05daff37419470273f2a8d898 100644
--- a/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/rng/RRNG.java
+++ b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/rng/RRNG.java
@@ -286,7 +286,7 @@ public class RRNG {
     }
 
     private static Kind intToKind(int kindAsInt) {
-        if (kindAsInt < 0 || kindAsInt >= Kind.VALUES.length) {
+        if (kindAsInt < 0 || kindAsInt >= Kind.VALUES.length || !Kind.VALUES[kindAsInt].isAvailable()) {
             throw RError.error(RError.NO_CALLER, RError.Message.RNG_NOT_IMPL_KIND, kindAsInt);
         }
         return Kind.VALUES[kindAsInt];
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 de4609f72d21751ab2a827dde1c41e9b106880fb..01052b8dfe1ba9f565c3a206e66957d0069257cd 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
@@ -1172,6 +1172,26 @@ Error in .Primitive(c("c", "b")) : string argument required
 #argv <- list('c');.Primitive(argv[[1]]);
 function (..., recursive = FALSE)  .Primitive("c")
 
+##com.oracle.truffle.r.test.builtins.TestBuiltin_RNGkind.testArgsCast
+#.Internal(RNGkind('abc', NULL))
+Error: RNGkind: unimplemented RNG kind -2147483648
+In addition: Warning message:
+NAs introduced by coercion
+
+##com.oracle.truffle.r.test.builtins.TestBuiltin_RNGkind.testArgsCast
+#.Internal(RNGkind(1L, 1L))
+[1] 3 4
+
+##com.oracle.truffle.r.test.builtins.TestBuiltin_RNGkind.testArgsCast
+#.Internal(RNGkind(NULL, 'abc'))
+Error: invalid Normal type in 'RNGkind'
+In addition: Warning message:
+NAs introduced by coercion
+
+##com.oracle.truffle.r.test.builtins.TestBuiltin_RNGkind.testArgsCast
+#.Internal(RNGkind(NULL, NULL))
+[1] 3 4
+
 ##com.oracle.truffle.r.test.builtins.TestBuiltin_Re.testRe
 #{ Re(1) }
 [1] 1
@@ -32172,6 +32192,22 @@ Warning messages:
 #argv <- structure(list(x = structure(c(0, 3313, 2963, 3175, 3339,     2762, 3276, 2610, 4485, 2977, 3030, 4532, 2753, 3949, 2865,     2282, 2179, 3000, 817, 3927, 1991, 3313, 0, 1318, 1326, 1294,     1498, 2218, 803, 1172, 2018, 1490, 1305, 645, 636, 521, 1014,     1365, 1033, 1460, 2868, 1802, 2963, 1318, 0, 204, 583, 206,     966, 677, 2256, 597, 172, 2084, 690, 1558, 1011, 925, 747,     285, 1511, 1616, 1175, 3175, 1326, 204, 0, 460, 409, 1136,     747, 2224, 714, 330, 2052, 739, 1550, 1059, 1077, 977, 280,     1662, 1786, 1381, 3339, 1294, 583, 460, 0, 785, 1545, 853,     2047, 1115, 731, 1827, 789, 1347, 1101, 1209, 1160, 340,     1794, 2196, 1588, 2762, 1498, 206, 409, 785, 0, 760, 1662,     2436, 460, 269, 2290, 714, 1764, 1035, 911, 583, 465, 1497,     1403, 937, 3276, 2218, 966, 1136, 1545, 760, 0, 1418, 3196,     460, 269, 2971, 1458, 2498, 1778, 1537, 1104, 1176, 2050,     650, 1455, 2610, 803, 677, 747, 853, 1662, 1418, 0, 1975,     1118, 895, 1936, 158, 1439, 425, 328, 591, 513, 995, 2068,     1019, 4485, 1172, 2256, 2224, 2047, 2436, 3196, 1975, 0,     2897, 2428, 676, 1817, 698, 1693, 2185, 2565, 1971, 2631,     3886, 2974, 2977, 2018, 597, 714, 1115, 460, 460, 1118, 2897,     0, 550, 2671, 1159, 2198, 1479, 1238, 805, 877, 1751, 949,     1155, 3030, 1490, 172, 330, 731, 269, 269, 895, 2428, 550,     0, 2280, 863, 1730, 1183, 1098, 851, 457, 1683, 1500, 1205,     4532, 1305, 2084, 2052, 1827, 2290, 2971, 1936, 676, 2671,     2280, 0, 1178, 668, 1762, 2250, 2507, 1799, 2700, 3231, 2937,     2753, 645, 690, 739, 789, 714, 1458, 158, 1817, 1159, 863,     1178, 0, 1281, 320, 328, 724, 471, 1048, 2108, 1157, 3949,     636, 1558, 1550, 1347, 1764, 2498, 1439, 698, 2198, 1730,     668, 1281, 0, 1157, 1724, 2010, 1273, 2097, 3188, 2409, 2865,     521, 1011, 1059, 1101, 1035, 1778, 425, 1693, 1479, 1183,     1762, 320, 1157, 0, 618, 1109, 792, 1011, 2428, 1363, 2282,     1014, 925, 1077, 1209, 911, 1537, 328, 2185, 1238, 1098,     2250, 328, 1724, 618, 0, 331, 856, 586, 2187, 898, 2179,     1365, 747, 977, 1160, 583, 1104, 591, 2565, 805, 851, 2507,     724, 2010, 1109, 331, 0, 821, 946, 1754, 428, 3000, 1033,     285, 280, 340, 465, 1176, 513, 1971, 877, 457, 1799, 471,     1273, 792, 856, 821, 0, 1476, 1827, 1249, 817, 1460, 1511,     1662, 1794, 1497, 2050, 995, 2631, 1751, 1683, 2700, 1048,     2097, 1011, 586, 946, 1476, 0, 2707, 1209, 3927, 2868, 1616,     1786, 2196, 1403, 650, 2068, 3886, 949, 1500, 3231, 2108,     3188, 2428, 2187, 1754, 1827, 2707, 0, 2105, 1991, 1802,     1175, 1381, 1588, 937, 1455, 1019, 2974, 1155, 1205, 2937,     1157, 2409, 1363, 898, 428, 1249, 1209, 2105, 0), .Dim = c(21L,     21L), .Dimnames = list(c('Athens', 'Barcelona', 'Brussels',     'Calais', 'Cherbourg', 'Cologne', 'Copenhagen', 'Geneva',     'Gibraltar', 'Hamburg', 'Hook of Holland', 'Lisbon', 'Lyons',     'Madrid', 'Marseilles', 'Milan', 'Munich', 'Paris', 'Rome',     'Stockholm', 'Vienna'), c('Athens', 'Barcelona', 'Brussels',     'Calais', 'Cherbourg', 'Cologne', 'Copenhagen', 'Geneva',     'Gibraltar', 'Hamburg', 'Hook of Holland', 'Lisbon', 'Lyons',     'Madrid', 'Marseilles', 'Milan', 'Munich', 'Paris', 'Rome',     'Stockholm', 'Vienna')))), .Names = 'x');do.call('NROW', argv)
 [1] 21
 
+##com.oracle.truffle.r.test.builtins.TestBuiltin_nzchar.keepNATests
+#nzchar(c('asdasd', NA), keepNA=FALSE)
+[1] TRUE TRUE
+
+##com.oracle.truffle.r.test.builtins.TestBuiltin_nzchar.keepNATests
+#nzchar(c('asdasd', NA), keepNA=TRUE)
+[1] TRUE   NA
+
+##com.oracle.truffle.r.test.builtins.TestBuiltin_nzchar.nonStringArgs
+#nzchar(NULL)
+logical(0)
+
+##com.oracle.truffle.r.test.builtins.TestBuiltin_nzchar.nonStringArgs
+#nzchar(list('x', 42, list('a'), list()))
+[1] TRUE TRUE TRUE TRUE
+
 ##com.oracle.truffle.r.test.builtins.TestBuiltin_nzchar.testnzchar1
 #argv <- list('./myTst2/man/DocLink-class.Rd');nzchar(argv[[1]]);
 [1] TRUE
@@ -32213,8 +32249,8 @@ logical(0)
 [1] TRUE
 
 ##com.oracle.truffle.r.test.builtins.TestBuiltin_nzchar.testnzchar9
-#argv <- list(c('  \036 The other major change was an error for asymmetric loss matrices,', '    prompted by a user query.  With L=loss asymmetric, the altered', '    priors were computed incorrectly - they were using L' instead of L.', '    Upshot - the tree would not not necessarily choose optimal splits', '    for the given loss matrix.  Once chosen, splits were evaluated', '    correctly.  The printed “improvement” values are of course the', '    wrong ones as well.  It is interesting that for my little test', '    case, with L quite asymmetric, the early splits in the tree are', '    unchanged - a good split still looks good.'));nzchar(argv[[1]]);
-Error: unexpected symbol in "argv <- list(c('  \036 The other major change was an error for asymmetric loss matrices,', '    prompted by a user query.  With L=loss asymmetric, the altered', '    priors were computed incor"
+#argv <- list(c('  \036 The other major change was an error for asymmetric loss matrices,', '    prompted by a user query.  With L=loss asymmetric, the altered', '    priors were computed incorrectly - they were using L\' instead of L.', '    Upshot - the tree would not not necessarily choose optimal splits', '    for the given loss matrix.  Once chosen, splits were evaluated', '    correctly.  The printed “improvement” values are of course the', '    wrong ones as well.  It is interesting that for my little test', '    case, with L quite asymmetric, the early splits in the tree are', '    unchanged - a good split still looks good.'));nzchar(argv[[1]]);
+[1] TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE
 
 ##com.oracle.truffle.r.test.builtins.TestBuiltin_oldClass.testGetClass
 #{ oldClass(NULL) }
@@ -37421,6 +37457,10 @@ expression(NULL)
 #{ typeof(parse(text = "foo", keep.source = FALSE, srcfile = NULL)[[1]]) }
 [1] "symbol"
 
+##com.oracle.truffle.r.test.builtins.TestBuiltin_parse.testArgumentsCasts
+#.Internal(parse(stdin(), c(1,2), c('expr1', 'expr2'), '?', '<weird-text', 'unknown'))
+expression(expr1)
+
 ##com.oracle.truffle.r.test.builtins.TestBuiltin_parse.testParseDataFrame
 #eval(parse(text=deparse(data.frame(x=c(1)))))
   x
@@ -37712,6 +37752,14 @@ character(0)
 #argv <- list(list(), NULL); .Internal(paste0(argv[[1]], argv[[2]]))
 character(0)
 
+##com.oracle.truffle.r.test.builtins.TestBuiltin_pathexpand.testArgsValidation
+#path.expand(42)
+Error in path.expand(42) : invalid 'path' argument
+
+##com.oracle.truffle.r.test.builtins.TestBuiltin_pathexpand.testArgsValidation
+#path.expand(NULL)
+Error in path.expand(NULL) : invalid 'path' argument
+
 ##com.oracle.truffle.r.test.builtins.TestBuiltin_pathexpand.testpathexpand1
 #argv <- list('/tmp/RtmptPgrXI/Pkgs/pkgA'); .Internal(path.expand(argv[[1]]))
 [1] "/tmp/RtmptPgrXI/Pkgs/pkgA"
@@ -37733,6 +37781,28 @@ character(0)
 #argv <- structure(list(e1 = structure(1, units = 'days', class = 'difftime'),     e2 = structure(14579, class = 'Date')), .Names = c('e1',     'e2'));do.call('+.Date', argv)
 [1] "2009-12-02"
 
+##com.oracle.truffle.r.test.builtins.TestBuiltin_pmatch.testArgumentsCasts
+#pmatch(1, NULL)
+[1] NA
+
+##com.oracle.truffle.r.test.builtins.TestBuiltin_pmatch.testArgumentsCasts
+#pmatch(1:5, c(1,3), duplicates.ok=42)
+[1]  1 NA  2 NA NA
+
+##com.oracle.truffle.r.test.builtins.TestBuiltin_pmatch.testArgumentsCasts
+#pmatch(1:5, c(1,3), nomatch='str')
+[1]  1 NA  2 NA NA
+Warning message:
+In pmatch(1:5, c(1, 3), nomatch = "str") : NAs introduced by coercion
+
+##com.oracle.truffle.r.test.builtins.TestBuiltin_pmatch.testArgumentsCasts
+#pmatch(1:5, c(1,3), nomatch=NULL)
+[1]  1 NA  2 NA NA
+
+##com.oracle.truffle.r.test.builtins.TestBuiltin_pmatch.testArgumentsCasts
+#pmatch(NULL, 1)
+integer(0)
+
 ##com.oracle.truffle.r.test.builtins.TestBuiltin_pmatch.testpmatch1
 #argv <- list('kendall', c('pearson', 'kendall', 'spearman'), 0L, TRUE); .Internal(pmatch(argv[[1]], argv[[2]], argv[[3]], argv[[4]]))
 [1] 2
@@ -37953,6 +38023,22 @@ numeric(0)
 [22] 42.000001  8.859155 59.952755  7.222226 27.000000  7.295775  6.377954
 [29]  2.407407 14.500000  7.295775 10.204727
 
+##com.oracle.truffle.r.test.builtins.TestBuiltin_pmin.testArgsCasting
+#.Internal(pmin(3, quote(a)))
+Error: invalid input type
+
+##com.oracle.truffle.r.test.builtins.TestBuiltin_pmin.testArgsCasting
+#pmin(c(1,2), c(3,0), na.rm='asd')
+Error in pmin(c(1, 2), c(3, 0), na.rm = "asd") : invalid 'na.rm' value
+
+##com.oracle.truffle.r.test.builtins.TestBuiltin_pmin.testArgsCasting
+#pmin(c(1,2), c(3,0), na.rm=NA)
+Error in pmin(c(1, 2), c(3, 0), na.rm = NA) : invalid 'na.rm' value
+
+##com.oracle.truffle.r.test.builtins.TestBuiltin_pmin.testArgsCasting
+#pmin(c(1,2), c(3,NA), na.rm=c(42, 0))
+[1] 1 2
+
 ##com.oracle.truffle.r.test.builtins.TestBuiltin_pmin.testPMin
 #{ pmin(7+42i) }
 Error in pmin(7 + (0+42i)) : invalid input type
@@ -39676,6 +39762,18 @@ Error in Summary.ordered(c(3L, 2L, 1L), FALSE, na.rm = FALSE) :
 Error in as.POSIXct.default(X[[i]], ...) :
   do not know how to convert 'X[[i]]' to class “POSIXct”
 
+##com.oracle.truffle.r.test.builtins.TestBuiltin_rank.testArgsCasts
+#.Internal(rank(as.raw(42), 42L, 'max'))
+Error: raw vectors cannot be sorted
+
+##com.oracle.truffle.r.test.builtins.TestBuiltin_rank.testArgsCasts
+#.Internal(rank(c(1,2), -3L, 'max'))
+Error: invalid 'length(xx)' value
+
+##com.oracle.truffle.r.test.builtins.TestBuiltin_rank.testArgsCasts
+#.Internal(rank(c(1,2), 2L, 'something'))
+Error: invalid ties.method for rank() [should never happen]
+
 ##com.oracle.truffle.r.test.builtins.TestBuiltin_rank.testRank
 #{ rank(c(10,100,100,1000)) }
 [1] 1.0 2.5 2.5 4.0
@@ -41489,6 +41587,38 @@ logical(0)
 #argv <- structure(list(x = c('#FF0000FF', '#FFFF00FF', '#00FF00FF')),     .Names = 'x');do.call('rev', argv)
 [1] "#00FF00FF" "#FFFF00FF" "#FF0000FF"
 
+##com.oracle.truffle.r.test.builtins.TestBuiltin_rm.basicTests
+# e <- new.env(); e$a <- 42; rm(list='a', envir=e); e$a
+NULL
+
+##com.oracle.truffle.r.test.builtins.TestBuiltin_rm.basicTests
+#tmp <- 42; f <- function() rm(list='tmp',inherits=T); f(); tmp
+Error: object 'tmp' not found
+
+##com.oracle.truffle.r.test.builtins.TestBuiltin_rm.basicTests
+#tmp <- 42; rm(list='tmp'); tmp
+Error: object 'tmp' not found
+
+##com.oracle.truffle.r.test.builtins.TestBuiltin_rm.basicTests
+#tmp <- 42; rm(tmp); tmp
+Error: object 'tmp' not found
+
+##com.oracle.truffle.r.test.builtins.TestBuiltin_rm.testArgsCasting
+#.Internal(remove(list=33, environment(), F))
+Error: invalid first argument
+
+##com.oracle.truffle.r.test.builtins.TestBuiltin_rm.testArgsCasting
+#tmp <- 42; rm(tmp, envir=42)
+Error in rm(tmp, envir = 42) : invalid 'envir' argument
+
+##com.oracle.truffle.r.test.builtins.TestBuiltin_rm.testArgsCasting
+#tmp <- 42; rm(tmp, envir=NULL)
+Error in rm(tmp, envir = NULL) : use of NULL environment is defunct
+
+##com.oracle.truffle.r.test.builtins.TestBuiltin_rm.testArgsCasting
+#tmp <- 42; rm(tmp, inherits='asd')
+Error in rm(tmp, inherits = "asd") : invalid 'inherits' argument
+
 ##com.oracle.truffle.r.test.builtins.TestBuiltin_round.testRound
 #{ round(-1.5) }
 [1] -2
@@ -41576,6 +41706,10 @@ logical(0)
 18     0.138     0.758      0.141      0.761
 19     0.122     0.775      0.124      0.777
 
+##com.oracle.truffle.r.test.builtins.TestBuiltin_row.testArgsCasts
+#.Internal(row('str'))
+Error: a matrix-like object is required as argument to 'row'
+
 ##com.oracle.truffle.r.test.builtins.TestBuiltin_row.testrow1
 #argv <- list(c(14L, 14L)); .Internal(row(argv[[1]]))
       [,1] [,2] [,3] [,4] [,5] [,6] [,7] [,8] [,9] [,10] [,11] [,12] [,13]
@@ -44126,6 +44260,15 @@ Error: unexpected symbol in "argv <- list('Error in cor(rnorm(10), NULL) : \n  s
 ##com.oracle.truffle.r.test.builtins.TestBuiltin_seterrmessage.testseterrmessage3
 #argv <- list('Error in validObject(.Object) : \n  invalid class “trackCurve” object: Unequal x,y lengths: 20, 10\n'); .Internal(seterrmessage(argv[[1]]))
 
+##com.oracle.truffle.r.test.builtins.TestBuiltin_setseed.testArgCasts
+#set.seed('hello world')
+Error in set.seed("hello world") : supplied seed is not a valid integer
+In addition: Warning message:
+In set.seed("hello world") : NAs introduced by coercion
+
+##com.oracle.truffle.r.test.builtins.TestBuiltin_setseed.testArgCasts
+#set.seed(FALSE)
+
 ##com.oracle.truffle.r.test.builtins.TestBuiltin_setseed.testsetseed1
 #argv <- list(1000, 0L, NULL); .Internal(set.seed(argv[[1]], argv[[2]], argv[[3]]))
 
diff --git a/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/builtins/TestBuiltin_RNGkind.java b/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/builtins/TestBuiltin_RNGkind.java
new file mode 100644
index 0000000000000000000000000000000000000000..4f797b4041b02226c776cb3b90df60803bdc6a99
--- /dev/null
+++ b/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/builtins/TestBuiltin_RNGkind.java
@@ -0,0 +1,40 @@
+/*
+ * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package com.oracle.truffle.r.test.builtins;
+
+import org.junit.Test;
+
+import com.oracle.truffle.r.test.TestBase;
+
+public class TestBuiltin_RNGkind extends TestBase {
+    @Test
+    public void testArgsCast() {
+        assertEval(".Internal(RNGkind(1L, 1L))");
+        assertEval(".Internal(RNGkind(NULL, NULL))");
+        // Note: GnuR casts 'abc' to int and then fails to find it, we do proper args validation in
+        // this case
+        assertEval(Output.IgnoreErrorMessage, ".Internal(RNGkind('abc', NULL))");
+        // Note: GnuR also prints warning about NAs
+        assertEval(Output.IgnoreErrorMessage, ".Internal(RNGkind(NULL, 'abc'))");
+    }
+}
diff --git a/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/builtins/TestBuiltin_nzchar.java b/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/builtins/TestBuiltin_nzchar.java
index 829f43019c2d1f91e4349d75ae0a68f00fefac67..c43232942555d24f347259f323d689e0fd7ed778 100644
--- a/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/builtins/TestBuiltin_nzchar.java
+++ b/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/builtins/TestBuiltin_nzchar.java
@@ -59,8 +59,7 @@ public class TestBuiltin_nzchar extends TestBase {
 
     @Test
     public void testnzchar9() {
-        assertEval(Ignored.Unknown,
-                        "argv <- list(c('  \\036 The other major change was an error for asymmetric loss matrices,', '    prompted by a user query.  With L=loss asymmetric, the altered', '    priors were computed incorrectly - they were using L' instead of L.', '    Upshot - the tree would not not necessarily choose optimal splits', '    for the given loss matrix.  Once chosen, splits were evaluated', '    correctly.  The printed “improvement” values are of course the', '    wrong ones as well.  It is interesting that for my little test', '    case, with L quite asymmetric, the early splits in the tree are', '    unchanged - a good split still looks good.'));nzchar(argv[[1]]);");
+        assertEval("argv <- list(c('  \\036 The other major change was an error for asymmetric loss matrices,', '    prompted by a user query.  With L=loss asymmetric, the altered', '    priors were computed incorrectly - they were using L\\' instead of L.', '    Upshot - the tree would not not necessarily choose optimal splits', '    for the given loss matrix.  Once chosen, splits were evaluated', '    correctly.  The printed “improvement” values are of course the', '    wrong ones as well.  It is interesting that for my little test', '    case, with L quite asymmetric, the early splits in the tree are', '    unchanged - a good split still looks good.'));nzchar(argv[[1]]);");
     }
 
     @Test
@@ -72,4 +71,16 @@ public class TestBuiltin_nzchar extends TestBase {
     public void testnzchar12() {
         assertEval("argv <- list('');do.call('nzchar', argv)");
     }
+
+    @Test
+    public void keepNATests() {
+        assertEval("nzchar(c('asdasd', NA), keepNA=TRUE)");
+        assertEval("nzchar(c('asdasd', NA), keepNA=FALSE)");
+    }
+
+    @Test
+    public void nonStringArgs() {
+        assertEval("nzchar(list('x', 42, list('a'), list()))");
+        assertEval("nzchar(NULL)");
+    }
 }
diff --git a/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/builtins/TestBuiltin_parse.java b/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/builtins/TestBuiltin_parse.java
index 214688f26e294f6826f495abc2e93984ac28d9b1..a0b0eeeb18192e2d6a8891bcb32e7c6919a57edf 100644
--- a/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/builtins/TestBuiltin_parse.java
+++ b/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/builtins/TestBuiltin_parse.java
@@ -51,4 +51,9 @@ public class TestBuiltin_parse extends TestBase {
         assertEval("parse(text='somethingthatdoesnotexist')");
         assertEval(Ignored.ImplementationError, "attributes(parse(text='somethingthatdoesnotexist'))");
     }
+
+    @Test
+    public void testArgumentsCasts() {
+        assertEval(".Internal(parse(stdin(), c(1,2), c('expr1', 'expr2'), '?', '<weird-text', 'unknown'))");
+    }
 }
diff --git a/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/builtins/TestBuiltin_pathexpand.java b/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/builtins/TestBuiltin_pathexpand.java
index a2a32c3e70587024cdb79118f7cdb9afc056e7f8..000d12c09fec9d6ff3992dda94035b761e426568 100644
--- a/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/builtins/TestBuiltin_pathexpand.java
+++ b/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/builtins/TestBuiltin_pathexpand.java
@@ -36,4 +36,10 @@ public class TestBuiltin_pathexpand extends TestBase {
     public void testpathexpand5() {
         assertEval("argv <- structure(list(path = '/tmp/RtmpagC9oa/Pkgs/exNSS4'),     .Names = 'path');do.call('path.expand', argv)");
     }
+
+    @Test
+    public void testArgsValidation() {
+        assertEval(Output.IgnoreErrorContext, "path.expand(NULL)");
+        assertEval(Output.IgnoreErrorContext, "path.expand(42)");
+    }
 }
diff --git a/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/builtins/TestBuiltin_pmatch.java b/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/builtins/TestBuiltin_pmatch.java
index 04cbdaf00cffb90b3e034b69d385dab1f876a3b1..d88d8ba6957cb9c134ce6025dd02968fee4bfe6c 100644
--- a/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/builtins/TestBuiltin_pmatch.java
+++ b/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/builtins/TestBuiltin_pmatch.java
@@ -56,4 +56,13 @@ public class TestBuiltin_pmatch extends TestBase {
     public void testpmatch8() {
         assertEval("argv <- list(character(0), c('labels', 'col', 'alpha', 'adj', 'cex', 'lineheight', 'font'), NA_integer_, TRUE); .Internal(pmatch(argv[[1]], argv[[2]], argv[[3]], argv[[4]]))");
     }
+
+    @Test
+    public void testArgumentsCasts() {
+        assertEval("pmatch(NULL, 1)");
+        assertEval("pmatch(1, NULL)");
+        assertEval("pmatch(1:5, c(1,3), nomatch=NULL)");
+        assertEval(Output.IgnoreWarningContext, "pmatch(1:5, c(1,3), nomatch='str')");
+        assertEval("pmatch(1:5, c(1,3), duplicates.ok=42)");
+    }
 }
diff --git a/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/builtins/TestBuiltin_pmin.java b/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/builtins/TestBuiltin_pmin.java
index 373b799a388d2d4e069122a6c11571f143008413..28c1a51ff1840c44ee62e6e5d46db9ec687c66f3 100644
--- a/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/builtins/TestBuiltin_pmin.java
+++ b/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/builtins/TestBuiltin_pmin.java
@@ -101,4 +101,12 @@ public class TestBuiltin_pmin extends TestBase {
         assertEval(Output.IgnoreErrorContext, "{ pmin(as.raw(42)) }");
         assertEval(Output.IgnoreErrorContext, "{ pmin(7+42i) }");
     }
+
+    @Test
+    public void testArgsCasting() {
+        assertEval("pmin(c(1,2), c(3,0), na.rm='asd')");
+        assertEval("pmin(c(1,2), c(3,0), na.rm=NA)");
+        assertEval("pmin(c(1,2), c(3,NA), na.rm=c(42, 0))");
+        assertEval(".Internal(pmin(3, quote(a)))");
+    }
 }
diff --git a/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/builtins/TestBuiltin_rank.java b/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/builtins/TestBuiltin_rank.java
index 6cef0b8e2653a1374f165ba816fabe68b489ed68..6d2c0d341e2f16777ae15837b3e50263a65d9663 100644
--- a/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/builtins/TestBuiltin_rank.java
+++ b/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/builtins/TestBuiltin_rank.java
@@ -85,4 +85,11 @@ public class TestBuiltin_rank extends TestBase {
         assertEval("{ rank(c(a=1,b=1,c=3,d=NA,e=3), na.last=NA, ties.method=\"min\") }");
         assertEval("{ rank(c(1000, 100, 100, NA, 1, 20), ties.method=\"first\") }");
     }
+
+    @Test
+    public void testArgsCasts() {
+        assertEval(".Internal(rank(c(1,2), -3L, 'max'))");
+        assertEval(".Internal(rank(c(1,2), 2L, 'something'))");
+        assertEval(".Internal(rank(as.raw(42), 42L, 'max'))");
+    }
 }
diff --git a/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/builtins/TestBuiltin_rm.java b/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/builtins/TestBuiltin_rm.java
new file mode 100644
index 0000000000000000000000000000000000000000..70ec6e7b32e6ab0c6c21f6de392faed39fe84f1f
--- /dev/null
+++ b/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/builtins/TestBuiltin_rm.java
@@ -0,0 +1,46 @@
+/*
+ * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package com.oracle.truffle.r.test.builtins;
+
+import org.junit.Test;
+
+import com.oracle.truffle.r.test.TestBase;
+
+public class TestBuiltin_rm extends TestBase {
+    @Test
+    public void basicTests() {
+        assertEval("tmp <- 42; rm(tmp); tmp");
+        assertEval("tmp <- 42; rm(list='tmp'); tmp");
+        assertEval(" e <- new.env(); e$a <- 42; rm(list='a', envir=e); e$a");
+        assertEval(Ignored.Unimplemented, "tmp <- 42; f <- function() rm(list='tmp',inherits=T); f(); tmp");
+    }
+
+    @Test
+    public void testArgsCasting() {
+        assertEval("tmp <- 42; rm(tmp, inherits='asd')");
+        assertEval(".Internal(remove(list=33, environment(), F))");
+        assertEval("tmp <- 42; rm(tmp, envir=NULL)");
+        assertEval("tmp <- 42; rm(tmp, envir=42)");
+    }
+}
diff --git a/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/builtins/TestBuiltin_row.java b/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/builtins/TestBuiltin_row.java
index 7f9604666f2001e9c8a6d0414c40d9f9c765fb71..e0fcedf85949acbb99019f99a3a809363cd754af 100644
--- a/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/builtins/TestBuiltin_row.java
+++ b/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/builtins/TestBuiltin_row.java
@@ -31,4 +31,9 @@ public class TestBuiltin_row extends TestBase {
     public void testrow3() {
         assertEval("argv <- list(0:1); .Internal(row(argv[[1]]))");
     }
+
+    @Test
+    public void testArgsCasts() {
+        assertEval(".Internal(row('str'))");
+    }
 }
diff --git a/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/builtins/TestBuiltin_rowMeans.java b/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/builtins/TestBuiltin_rowMeans.java
index 8e14c8b34e15ed811d87e96d40a22fa66abbae11..8d61e4214075bd634e359c1047addd67c48d47a8 100644
--- a/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/builtins/TestBuiltin_rowMeans.java
+++ b/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/builtins/TestBuiltin_rowMeans.java
@@ -58,8 +58,8 @@ public class TestBuiltin_rowMeans extends TestBase {
         // Whichever value(NA or NaN) is first in the row will be returned for that row.
         assertEval("{rowMeans(matrix(c(NA,NaN,NaN,NA),ncol=2,nrow=2))}");
 
+        assertEval("{x<-matrix(c(\"1\",\"2\",\"3\",\"4\"),ncol=2);rowMeans(x)}");
         // Error message mismatch
         assertEval(Ignored.Unknown, "{rowMeans(matrix(NA,NA,NA),TRUE)}");
-        assertEval(Output.IgnoreErrorContext, "{x<-matrix(c(\"1\",\"2\",\"3\",\"4\"),ncol=2);rowMeans(x)}");
     }
 }
diff --git a/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/builtins/TestBuiltin_setseed.java b/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/builtins/TestBuiltin_setseed.java
index 6b4512b2807a4861c1a47a30de6d6ee8af8ffb35..99ad536d7fe6b52f8627208a6f38b590cf633b64 100644
--- a/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/builtins/TestBuiltin_setseed.java
+++ b/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/builtins/TestBuiltin_setseed.java
@@ -17,24 +17,26 @@ import com.oracle.truffle.r.test.TestBase;
 // Checkstyle: stop line length check
 public class TestBuiltin_setseed extends TestBase {
 
+    // Note: all the unimplemented tests fail on unimplemented RNG of given kind (2nd argument)
+
     @Test
     public void testsetseed1() {
-        assertEval(Ignored.Unknown, "argv <- list(1000, 0L, NULL); .Internal(set.seed(argv[[1]], argv[[2]], argv[[3]]))");
+        assertEval(Ignored.Unimplemented, "argv <- list(1000, 0L, NULL); .Internal(set.seed(argv[[1]], argv[[2]], argv[[3]]))");
     }
 
     @Test
     public void testsetseed2() {
-        assertEval(Ignored.Unknown, "argv <- list(77, 2L, NULL); .Internal(set.seed(argv[[1]], argv[[2]], argv[[3]]))");
+        assertEval(Ignored.Unimplemented, "argv <- list(77, 2L, NULL); .Internal(set.seed(argv[[1]], argv[[2]], argv[[3]]))");
     }
 
     @Test
     public void testsetseed3() {
-        assertEval(Ignored.Unknown, "argv <- list(123, 6L, NULL); .Internal(set.seed(argv[[1]], argv[[2]], argv[[3]]))");
+        assertEval(Ignored.Unimplemented, "argv <- list(123, 6L, NULL); .Internal(set.seed(argv[[1]], argv[[2]], argv[[3]]))");
     }
 
     @Test
     public void testsetseed4() {
-        assertEval(Ignored.Unknown, "argv <- list(77, 4L, NULL); .Internal(set.seed(argv[[1]], argv[[2]], argv[[3]]))");
+        assertEval(Ignored.Unimplemented, "argv <- list(77, 4L, NULL); .Internal(set.seed(argv[[1]], argv[[2]], argv[[3]]))");
     }
 
     @Test
@@ -49,11 +51,17 @@ public class TestBuiltin_setseed extends TestBase {
 
     @Test
     public void testsetseed7() {
-        assertEval(Ignored.Unknown, "argv <- list(123, 7L, NULL); .Internal(set.seed(argv[[1]], argv[[2]], argv[[3]]))");
+        assertEval(Ignored.Unimplemented, "argv <- list(123, 7L, NULL); .Internal(set.seed(argv[[1]], argv[[2]], argv[[3]]))");
     }
 
     @Test
     public void testsetseed8() {
         assertEval("argv <- list(NULL, NULL, NULL); .Internal(set.seed(argv[[1]], argv[[2]], argv[[3]]))");
     }
+
+    @Test
+    public void testArgCasts() {
+        assertEval(Output.IgnoreErrorMessage, "set.seed('hello world')");
+        assertEval("set.seed(FALSE)");
+    }
 }