diff --git a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/ConditionFunctions.java b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/ConditionFunctions.java
index b4b560584bdae56422dd18f0ed0ea4f4e13a089e..cd3e5e552c64cbf95b9acc1256f0a0d50277246a 100644
--- a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/ConditionFunctions.java
+++ b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/ConditionFunctions.java
@@ -11,6 +11,7 @@
  */
 package com.oracle.truffle.r.nodes.builtin.base;
 
+import static com.oracle.truffle.r.nodes.builtin.CastBuilder.Predef.*;
 import static com.oracle.truffle.r.runtime.RErrorHandling.getHandlerStack;
 import static com.oracle.truffle.r.runtime.RVisibility.OFF;
 import static com.oracle.truffle.r.runtime.builtins.RBehavior.COMPLEX;
@@ -18,7 +19,6 @@ 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.Fallback;
 import com.oracle.truffle.api.dsl.Specialization;
 import com.oracle.truffle.r.nodes.builtin.CastBuilder;
 import com.oracle.truffle.r.nodes.builtin.RBuiltinNode;
@@ -52,27 +52,29 @@ public class ConditionFunctions {
 
     @RBuiltin(name = ".addCondHands", visibility = OFF, kind = INTERNAL, parameterNames = {"classes", "handlers", "parentenv", "target", "calling"}, behavior = COMPLEX)
     public abstract static class AddCondHands extends RBuiltinNode {
+        @Override
+        protected void createCasts(CastBuilder casts) {
+            casts.arg("classes").mustBe(nullValue().or(stringValue())).asStringVector();
+            casts.arg("handlers").mustBe(nullValue().or(instanceOf(RList.class)));
+            casts.arg("calling").asLogicalVector().findFirst();
+        }
 
         @SuppressWarnings("unused")
         @Specialization(guards = "isRNull(classes) || isRNull(handlers)")
         @TruffleBoundary
         protected Object addCondHands(Object classes, Object handlers, Object parentEnv, Object target, byte calling) {
-            RContext.getInstance().setVisible(false);
             return getHandlerStack();
         }
 
-        @Specialization(guards = "classes.getLength() == handlers.getLength()")
+        @Specialization
         @TruffleBoundary
         protected Object addCondHands(RAbstractStringVector classes, RList handlers, REnvironment parentEnv, Object target, byte calling) {
-            RContext.getInstance().setVisible(false);
+            if (classes.getLength() != handlers.getLength()) {
+                throw RError.error(this, RError.Message.BAD_HANDLER_DATA);
+            }
             return RErrorHandling.createHandlers(classes, handlers, parentEnv, target, calling);
         }
 
-        @SuppressWarnings("unused")
-        @Fallback
-        protected Object fallback(Object classesObj, Object handlersObj, Object parentEnv, Object target, byte calling) {
-            throw RError.error(this, RError.Message.BAD_HANDLER_DATA);
-        }
     }
 
     @RBuiltin(name = ".resetCondHands", visibility = OFF, kind = INTERNAL, parameterNames = {"stack"}, behavior = COMPLEX)
@@ -87,34 +89,39 @@ public class ConditionFunctions {
     }
 
     public abstract static class RestartAdapter extends RBuiltinNode {
-        public static boolean lengthok(Object restart) {
-            return (restart instanceof RList) && ((RList) restart).getLength() >= 2;
+        protected void checkLength(RList restart) {
+            if (restart.getLength() < 2) {
+                throw RError.error(this, RError.Message.BAD_RESTART);
+            }
         }
 
-        protected RError badRestart() throws RError {
-            throw RError.error(this, RError.Message.BAD_RESTART);
+        protected void restart(CastBuilder casts) {
+            casts.arg("restart").mustBe(instanceOf(RList.class), RError.Message.BAD_RESTART);
         }
+
     }
 
     @RBuiltin(name = ".addRestart", kind = INTERNAL, parameterNames = "restart", behavior = COMPLEX)
     public abstract static class AddRestart extends RestartAdapter {
+        @Override
+        public void createCasts(CastBuilder casts) {
+            restart(casts);
+        }
+
         @Specialization
         protected Object addRestart(RList restart) {
+            checkLength(restart);
             RErrorHandling.addRestart(restart);
             return RNull.instance;
         }
 
-        @Specialization(guards = "lengthok(restart)")
-        protected Object addRestart(@SuppressWarnings("unused") Object restart) {
-            throw badRestart();
-        }
     }
 
     @RBuiltin(name = ".getRestart", kind = INTERNAL, parameterNames = "restart", behavior = COMPLEX)
     public abstract static class GetRestart extends RBuiltinNode {
         @Override
         protected void createCasts(CastBuilder casts) {
-            casts.toInteger(0);
+            casts.arg("restart").asIntegerVector().findFirst();
         }
 
         @Specialization
@@ -126,8 +133,14 @@ public class ConditionFunctions {
 
     @RBuiltin(name = ".invokeRestart", kind = INTERNAL, parameterNames = {"restart", "args"}, behavior = COMPLEX)
     public abstract static class InvokeRestart extends RestartAdapter {
-        @Specialization(guards = "lengthok(restart)")
+        @Override
+        public void createCasts(CastBuilder casts) {
+            restart(casts);
+        }
+
+        @Specialization
         protected RNull invokeRestart(RList restart, Object args) {
+            checkLength(restart);
             if (RErrorHandling.invokeRestart(restart, args) == null) {
                 throw RError.error(this, RError.Message.RESTART_NOT_ON_STACK);
             } else {
@@ -135,11 +148,6 @@ public class ConditionFunctions {
             }
         }
 
-        @SuppressWarnings("unused")
-        @Fallback
-        protected Object invokeRestart(Object restart, Object args) {
-            throw badRestart();
-        }
     }
 
     @RBuiltin(name = ".signalCondition", kind = INTERNAL, parameterNames = {"condition", "msg", "call"}, behavior = COMPLEX)
@@ -161,28 +169,43 @@ public class ConditionFunctions {
 
     @RBuiltin(name = "seterrmessage", visibility = OFF, kind = INTERNAL, parameterNames = "msg", behavior = COMPLEX)
     public abstract static class Seterrmessage extends RBuiltinNode {
+        @Override
+        public void createCasts(CastBuilder casts) {
+            casts.arg("msg").defaultError(RError.Message.ERR_MSG_MUST_BE_STRING).mustBe(stringValue()).asStringVector().mustBe(size(1)).findFirst();
+        }
+
         @Specialization
-        protected RNull seterrmessage(RAbstractStringVector msg) {
+        protected RNull seterrmessage(String msg) {
             RContext.getInstance().setVisible(false);
-            RErrorHandling.seterrmessage(msg.getDataAt(0));
+            RErrorHandling.seterrmessage(msg);
             return RNull.instance;
         }
     }
 
     @RBuiltin(name = ".dfltWarn", kind = INTERNAL, parameterNames = {"message", "call"}, behavior = COMPLEX)
     public abstract static class DfltWarn extends RBuiltinNode {
+        @Override
+        public void createCasts(CastBuilder casts) {
+            casts.arg("message").defaultError(RError.Message.ERR_MSG_BAD).mustBe(stringValue()).asStringVector().mustBe(size(1)).findFirst();
+        }
+
         @Specialization
-        protected RNull dfltWarn(RAbstractStringVector msg, Object call) {
-            RErrorHandling.dfltWarn(msg.getDataAt(0), call);
+        protected RNull dfltWarn(String msg, Object call) {
+            RErrorHandling.dfltWarn(msg, call);
             return RNull.instance;
         }
     }
 
     @RBuiltin(name = ".dfltStop", kind = INTERNAL, parameterNames = {"message", "call"}, behavior = COMPLEX)
     public abstract static class DfltStop extends RBuiltinNode {
+        @Override
+        public void createCasts(CastBuilder casts) {
+            casts.arg("message").defaultError(RError.Message.ERR_MSG_BAD).mustBe(stringValue()).asStringVector().mustBe(size(1)).findFirst();
+        }
+
         @Specialization
-        protected Object dfltStop(RAbstractStringVector message, Object call) {
-            RErrorHandling.dfltStop(message.getDataAt(0), call);
+        protected Object dfltStop(String message, Object call) {
+            RErrorHandling.dfltStop(message, call);
             return RNull.instance;
         }
     }
diff --git a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/DelayedAssign.java b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/DelayedAssign.java
index f168a9091a6ca09a23607df8c4191f6e0b291c4b..1c12e42ec82f04aaf12ebecf895b9cc553fa94dc 100644
--- a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/DelayedAssign.java
+++ b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/DelayedAssign.java
@@ -22,6 +22,7 @@
  */
 package com.oracle.truffle.r.nodes.builtin.base;
 
+import static com.oracle.truffle.r.nodes.builtin.CastBuilder.Predef.*;
 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;
@@ -30,6 +31,7 @@ import com.oracle.truffle.api.CompilerDirectives.TruffleBoundary;
 import com.oracle.truffle.api.dsl.Specialization;
 import com.oracle.truffle.api.profiles.BranchProfile;
 import com.oracle.truffle.r.nodes.RASTUtils;
+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;
@@ -37,7 +39,6 @@ import com.oracle.truffle.r.runtime.data.RDataFactory;
 import com.oracle.truffle.r.runtime.data.RNull;
 import com.oracle.truffle.r.runtime.data.RPromise.Closure;
 import com.oracle.truffle.r.runtime.data.RPromise.PromiseState;
-import com.oracle.truffle.r.runtime.data.model.RAbstractStringVector;
 import com.oracle.truffle.r.runtime.env.REnvironment;
 import com.oracle.truffle.r.runtime.env.REnvironment.PutException;
 
@@ -46,10 +47,16 @@ public abstract class DelayedAssign extends RBuiltinNode {
 
     private final BranchProfile errorProfile = BranchProfile.create();
 
+    @Override
+    protected void createCasts(CastBuilder casts) {
+        casts.arg("x").mustBe(stringValue()).asStringVector().mustBe(notEmpty(), RError.Message.INVALID_FIRST_ARGUMENT).findFirst();
+        casts.arg("eval.env").mustBe(nullValue().not(), RError.Message.USE_NULL_ENV_DEFUNCT).mustBe(instanceOf(REnvironment.class));
+        casts.arg("assign.env").mustBe(nullValue().not(), RError.Message.USE_NULL_ENV_DEFUNCT).mustBe(instanceOf(REnvironment.class));
+    }
+
     @Specialization
     @TruffleBoundary
-    protected Object doDelayedAssign(RAbstractStringVector nameVec, Object value, REnvironment evalEnv, REnvironment assignEnv) {
-        String name = nameVec.getDataAt(0);
+    protected Object doDelayedAssign(String name, Object value, REnvironment evalEnv, REnvironment assignEnv) {
         try {
             assignEnv.put(name, RDataFactory.createPromise(PromiseState.Explicit, Closure.create(RASTUtils.createNodeForValue(value)), evalEnv.getFrame()));
             return RNull.instance;
diff --git a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/DynLoadFunctions.java b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/DynLoadFunctions.java
index 06b412f7ff1036479ec6735517bce5f188b53a8a..09557dc390d69f495316c6f359cf837476aad32c 100644
--- a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/DynLoadFunctions.java
+++ b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/DynLoadFunctions.java
@@ -22,6 +22,7 @@
  */
 package com.oracle.truffle.r.nodes.builtin.base;
 
+import static com.oracle.truffle.r.nodes.builtin.CastBuilder.Predef.*;
 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.RBehavior.READS_STATE;
@@ -30,20 +31,17 @@ import static com.oracle.truffle.r.runtime.builtins.RBuiltinKind.INTERNAL;
 import java.util.ArrayList;
 
 import com.oracle.truffle.api.CompilerDirectives.TruffleBoundary;
-import com.oracle.truffle.api.dsl.Fallback;
 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.RInternalError;
 import com.oracle.truffle.r.runtime.RRuntime;
-import com.oracle.truffle.r.runtime.RType;
 import com.oracle.truffle.r.runtime.builtins.RBuiltin;
 import com.oracle.truffle.r.runtime.data.RDataFactory;
 import com.oracle.truffle.r.runtime.data.RExternalPtr;
 import com.oracle.truffle.r.runtime.data.RList;
 import com.oracle.truffle.r.runtime.data.RNull;
-import com.oracle.truffle.r.runtime.data.model.RAbstractLogicalVector;
 import com.oracle.truffle.r.runtime.data.model.RAbstractStringVector;
 import com.oracle.truffle.r.runtime.ffi.DLL;
 import com.oracle.truffle.r.runtime.ffi.DLL.DLLException;
@@ -57,25 +55,19 @@ public class DynLoadFunctions {
 
     @RBuiltin(name = "dyn.load", visibility = OFF, kind = INTERNAL, parameterNames = {"lib", "local", "now", "unused"}, behavior = COMPLEX)
     public abstract static class DynLoad extends RBuiltinNode {
-
         @Override
         protected void createCasts(CastBuilder casts) {
-            // TODO: not sure if the behavior is 100% compliant
-            casts.arg("now").asLogicalVector().findFirst();
+            casts.arg("lib").mustBe(stringValue()).asStringVector().mustBe(size(1), RError.Message.CHAR_ARGUMENT).findFirst();
+            casts.arg("local").asLogicalVector().findFirst().map(toBoolean());
+            casts.arg("now").asLogicalVector().findFirst().map(toBoolean());
+            casts.arg("unused").mustBe(stringValue()).asStringVector().findFirst();
         }
 
         @Specialization
         @TruffleBoundary
-        protected RList doDynLoad(RAbstractStringVector libVec, RAbstractLogicalVector localVec, byte now, @SuppressWarnings("unused") String unused) {
-            // Length checked by GnuR
-            if (libVec.getLength() > 1) {
-                throw RError.error(this, RError.Message.TYPE_EXPECTED, RType.Character.getName());
-            }
-            String lib = libVec.getDataAt(0);
-            // Length not checked by GnuR
-            byte local = localVec.getDataAt(0);
+        protected RList doDynLoad(String lib, boolean local, boolean now, @SuppressWarnings("unused") String unused) {
             try {
-                DLLInfo dllInfo = DLL.loadPackageDLL(lib, asBoolean(local), asBoolean(now));
+                DLLInfo dllInfo = DLL.loadPackageDLL(lib, local, now);
                 return dllInfo.toRList();
             } catch (DLLException ex) {
                 // This is not a recoverable error
@@ -85,13 +77,15 @@ public class DynLoadFunctions {
             }
         }
 
-        private static boolean asBoolean(byte b) {
-            return b == RRuntime.LOGICAL_TRUE ? true : false;
-        }
     }
 
     @RBuiltin(name = "dyn.unload", visibility = OFF, kind = INTERNAL, parameterNames = {"lib"}, behavior = COMPLEX)
     public abstract static class DynUnload extends RBuiltinNode {
+        @Override
+        protected void createCasts(CastBuilder casts) {
+            casts.arg("lib").mustBe(stringValue()).asStringVector().mustBe(size(1), RError.Message.CHAR_ARGUMENT).findFirst();
+        }
+
         @Specialization
         @TruffleBoundary
         protected RNull doDynunload(RAbstractStringVector lib) {
@@ -124,12 +118,18 @@ public class DynLoadFunctions {
         }
     }
 
-    @RBuiltin(name = "is.loaded", kind = INTERNAL, parameterNames = {"symbol", "package", "type"}, behavior = READS_STATE)
+    @RBuiltin(name = "is.loaded", kind = INTERNAL, parameterNames = {"symbol", "PACKAGE", "type"}, behavior = READS_STATE)
     public abstract static class IsLoaded extends RBuiltinNode {
+        @Override
+        protected void createCasts(CastBuilder casts) {
+            casts.arg("symbol").mustBe(stringValue()).asStringVector().mustBe(notEmpty()).findFirst();
+            casts.arg("PACKAGE").mustBe(stringValue()).asStringVector().mustBe(notEmpty()).findFirst();
+            casts.arg("type").mustBe(stringValue()).asStringVector().mustBe(notEmpty()).findFirst();
+        }
+
         @Specialization
         @TruffleBoundary
-        protected byte isLoaded(RAbstractStringVector symbol, RAbstractStringVector packageName, RAbstractStringVector typeVec) {
-            String type = typeVec.getDataAt(0);
+        protected byte isLoaded(String symbol, String packageName, String type) {
             NativeSymbolType nst = null;
             switch (type) {
                 case "":
@@ -147,24 +147,22 @@ public class DynLoadFunctions {
                     // Not an error in GnuR
             }
             DLL.RegisteredNativeSymbol rns = new DLL.RegisteredNativeSymbol(nst, null, null);
-            boolean found = DLL.findSymbol(symbol.getDataAt(0), packageName.getDataAt(0), rns) != DLL.SYMBOL_NOT_FOUND;
+            boolean found = DLL.findSymbol(symbol, packageName, rns) != DLL.SYMBOL_NOT_FOUND;
             return RRuntime.asLogical(found);
         }
     }
 
-    @RBuiltin(name = "getSymbolInfo", kind = INTERNAL, parameterNames = {"symbol", "package", "withReg"}, behavior = READS_STATE)
+    @RBuiltin(name = "getSymbolInfo", kind = INTERNAL, parameterNames = {"symbol", "package", "withRegistrationInfo"}, behavior = READS_STATE)
     public abstract static class GetSymbolInfo extends RBuiltinNode {
-
         @Override
         protected void createCasts(CastBuilder casts) {
-            // TODO: not sure if the behavior is 100% compliant
-            casts.arg("withReg").asLogicalVector().findFirst();
+            casts.arg("symbol").mustBe(stringValue()).asStringVector().mustBe(notEmpty()).findFirst();
+            casts.arg("withRegistrationInfo").mustBe(logicalValue()).asLogicalVector().findFirst().map(toBoolean());
         }
 
         @Specialization
         @TruffleBoundary
-        protected Object getSymbolInfo(RAbstractStringVector symbolVec, String packageName, byte withReg) {
-            String symbol = symbolVec.getDataAt(0);
+        protected Object getSymbolInfo(String symbol, String packageName, boolean withReg) {
             DLL.RegisteredNativeSymbol rns = DLL.RegisteredNativeSymbol.any();
             long f = DLL.findSymbol(RRuntime.asString(symbol), packageName, rns);
             SymbolInfo symbolInfo = null;
@@ -176,7 +174,7 @@ public class DynLoadFunctions {
 
         @Specialization(guards = "isDLLInfo(externalPtr)")
         @TruffleBoundary
-        protected Object getSymbolInfo(RAbstractStringVector symbolVec, RExternalPtr externalPtr, byte withReg) {
+        protected Object getSymbolInfo(RAbstractStringVector symbolVec, RExternalPtr externalPtr, boolean withReg) {
             DLL.DLLInfo dllInfo = DLL.getDLLInfoForId((int) externalPtr.getAddr());
             if (dllInfo == null) {
                 throw RError.error(this, RError.Message.REQUIRES_NAME_DLLINFO);
@@ -192,20 +190,14 @@ public class DynLoadFunctions {
             return getResult(symbolInfo, withReg);
         }
 
-        private static Object getResult(DLL.SymbolInfo symbolInfo, byte withReg) {
+        private static Object getResult(DLL.SymbolInfo symbolInfo, boolean withReg) {
             if (symbolInfo != null) {
-                return symbolInfo.createRSymbolObject(new DLL.RegisteredNativeSymbol(DLL.NativeSymbolType.Any, null, null), RRuntime.fromLogical(withReg));
+                return symbolInfo.createRSymbolObject(new DLL.RegisteredNativeSymbol(DLL.NativeSymbolType.Any, null, null), withReg);
             } else {
                 return RNull.instance;
             }
         }
 
-        @SuppressWarnings("unused")
-        @Fallback
-        protected Object getSymbolInfo(Object symbol, Object packageName, Object withReg) {
-            throw RError.error(this, RError.Message.REQUIRES_NAME_DLLINFO);
-        }
-
         protected static boolean isDLLInfo(RExternalPtr externalPtr) {
             return DLL.isDLLInfo(externalPtr);
         }
diff --git a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/FileFunctions.java b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/FileFunctions.java
index 33546b1db6d04b2303b66e91a9fca9b7f9e497f7..02dc87de5d32a8caa7a0e118b5ddb8a84dcff7c8 100644
--- a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/FileFunctions.java
+++ b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/FileFunctions.java
@@ -11,6 +11,7 @@
  */
 package com.oracle.truffle.r.nodes.builtin.base;
 
+import static com.oracle.truffle.r.nodes.builtin.CastBuilder.Predef.*;
 import static com.oracle.truffle.r.runtime.RVisibility.OFF;
 import static com.oracle.truffle.r.runtime.builtins.RBehavior.IO;
 import static com.oracle.truffle.r.runtime.builtins.RBuiltinKind.INTERNAL;
@@ -45,7 +46,6 @@ import java.util.stream.Stream;
 
 import com.oracle.truffle.api.CompilerDirectives;
 import com.oracle.truffle.api.CompilerDirectives.TruffleBoundary;
-import com.oracle.truffle.api.dsl.Fallback;
 import com.oracle.truffle.api.dsl.Specialization;
 import com.oracle.truffle.r.nodes.builtin.CastBuilder;
 import com.oracle.truffle.r.nodes.builtin.RBuiltinNode;
@@ -62,6 +62,8 @@ import com.oracle.truffle.r.runtime.data.RList;
 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.RSymbol;
+import com.oracle.truffle.r.runtime.data.RTypedValue;
 import com.oracle.truffle.r.runtime.data.model.RAbstractContainer;
 import com.oracle.truffle.r.runtime.data.model.RAbstractStringVector;
 import com.oracle.truffle.r.runtime.ffi.RFFIFactory;
@@ -78,15 +80,13 @@ public class FileFunctions {
 
         @Override
         protected void createCasts(CastBuilder casts) {
-            casts.toInteger(1);
+            casts.arg("names").mustBe(stringValue()).asStringVector();
+            casts.arg("mode").asIntegerVector().findFirst().mustBe(gte(0).and(lte(7)));
         }
 
         @Specialization
         @TruffleBoundary
         protected Object fileAccess(RAbstractStringVector names, int mode) {
-            if (mode == RRuntime.INT_NA || mode < 0 || mode > 7) {
-                throw RError.error(this, RError.Message.INVALID_ARGUMENT, "mode");
-            }
             int[] data = new int[names.getLength()];
             for (int i = 0; i < data.length; i++) {
                 File file = new File(Utils.tildeExpand(names.getDataAt(i)));
@@ -110,6 +110,12 @@ public class FileFunctions {
 
     @RBuiltin(name = "file.append", kind = INTERNAL, parameterNames = {"file1", "file2"}, behavior = IO)
     public abstract static class FileAppend extends RBuiltinNode {
+        @Override
+        protected void createCasts(CastBuilder casts) {
+            casts.arg("file1").mustBe(stringValue()).asStringVector();
+            casts.arg("file1").mustBe(stringValue()).asStringVector();
+        }
+
         @Specialization
         @TruffleBoundary
         protected RLogicalVector doFileAppend(RAbstractStringVector file1Vec, RAbstractStringVector file2Vec) {
@@ -200,6 +206,11 @@ public class FileFunctions {
 
     @RBuiltin(name = "file.create", kind = INTERNAL, parameterNames = {"vec", "showWarnings"}, behavior = IO)
     public abstract static class FileCreate extends RBuiltinNode {
+        @Override
+        protected void createCasts(CastBuilder casts) {
+            casts.arg("vec").mustBe(stringValue()).asStringVector();
+            casts.arg("showWarnings").asLogicalVector().findFirst().mapIf(logicalNA(), constant(RRuntime.LOGICAL_FALSE));
+        }
 
         @Specialization
         @TruffleBoundary
@@ -225,11 +236,6 @@ public class FileFunctions {
             return RDataFactory.createLogicalVector(status, RDataFactory.COMPLETE_VECTOR);
         }
 
-        @Fallback
-        @TruffleBoundary
-        protected Object doFileCreate(@SuppressWarnings("unused") Object x, @SuppressWarnings("unused") Object y) {
-            throw RError.error(this, RError.Message.INVALID_ARGUMENT, "file");
-        }
     }
 
     @RBuiltin(name = "file.info", kind = INTERNAL, parameterNames = {"fn", "extra_cols"}, behavior = IO)
@@ -394,7 +400,13 @@ public class FileFunctions {
         }
     }
 
-    abstract static class FileLinkAdaptor extends RBuiltinNode {
+    private abstract static class FileLinkAdaptor extends RBuiltinNode {
+        @Override
+        protected void createCasts(CastBuilder casts) {
+            casts.arg("from").mustBe(stringValue(), RError.Message.INVALID_FIRST_FILENAME).asStringVector();
+            casts.arg("to").mustBe(stringValue(), RError.Message.INVALID_SECOND_FILENAME).asStringVector();
+        }
+
         protected Object doFileLink(RAbstractStringVector vecFrom, RAbstractStringVector vecTo, boolean symbolic) {
             int lenFrom = vecFrom.getLength();
             int lenTo = vecTo.getLength();
@@ -440,11 +452,6 @@ public class FileFunctions {
             return doFileLink(vecFrom, vecTo, false);
         }
 
-        @Fallback
-        @TruffleBoundary
-        protected Object doFileLink(@SuppressWarnings("unused") Object from, @SuppressWarnings("unused") Object to) {
-            throw RError.error(this, RError.Message.INVALID_ARGUMENT, "file");
-        }
     }
 
     @RBuiltin(name = "file.symlink", kind = INTERNAL, parameterNames = {"from", "to"}, behavior = IO)
@@ -455,16 +462,16 @@ public class FileFunctions {
             return doFileLink(vecFrom, vecTo, true);
         }
 
-        @Fallback
-        @TruffleBoundary
-        protected Object doFileSymLink(@SuppressWarnings("unused") Object from, @SuppressWarnings("unused") Object to) {
-            throw RError.error(this, RError.Message.INVALID_ARGUMENT, "file");
-        }
     }
 
-    @RBuiltin(name = "file.remove", kind = INTERNAL, parameterNames = {"vec"}, behavior = IO)
+    @RBuiltin(name = "file.remove", kind = INTERNAL, parameterNames = {"file"}, behavior = IO)
     public abstract static class FileRemove extends RBuiltinNode {
 
+        @Override
+        protected void createCasts(CastBuilder casts) {
+            casts.arg("file").mustBe(stringValue(), RError.Message.INVALID_FIRST_FILENAME).asStringVector();
+        }
+
         @Specialization
         @TruffleBoundary
         protected Object doFileRemove(RAbstractStringVector vec) {
@@ -485,15 +492,16 @@ public class FileFunctions {
             return RDataFactory.createLogicalVector(status, RDataFactory.COMPLETE_VECTOR);
         }
 
-        @Fallback
-        @TruffleBoundary
-        protected Object doFileRemove(@SuppressWarnings("unused") Object x) {
-            throw RError.error(this, RError.Message.INVALID_ARGUMENT, "file");
-        }
     }
 
     @RBuiltin(name = "file.rename", kind = INTERNAL, parameterNames = {"from", "to"}, behavior = IO)
     public abstract static class FileRename extends RBuiltinNode {
+        @Override
+        protected void createCasts(CastBuilder casts) {
+            casts.arg("from").mustBe(stringValue()).asStringVector();
+            casts.arg("to").mustBe(stringValue()).asStringVector();
+        }
+
         @Specialization
         @TruffleBoundary
         protected Object doFileRename(RAbstractStringVector vecFrom, RAbstractStringVector vecTo) {
@@ -520,16 +528,16 @@ public class FileFunctions {
             return RDataFactory.createLogicalVector(status, RDataFactory.COMPLETE_VECTOR);
         }
 
-        @Fallback
-        @TruffleBoundary
-        protected Object doFileRename(@SuppressWarnings("unused") Object from, @SuppressWarnings("unused") Object to) {
-            throw RError.error(this, RError.Message.INVALID_ARGUMENT, "file");
-        }
     }
 
-    @RBuiltin(name = "file.exists", kind = INTERNAL, parameterNames = {"vec"}, behavior = IO)
+    @RBuiltin(name = "file.exists", kind = INTERNAL, parameterNames = {"file"}, behavior = IO)
     public abstract static class FileExists extends RBuiltinNode {
 
+        @Override
+        protected void createCasts(CastBuilder casts) {
+            casts.arg("file").mustBe(stringValue()).asStringVector();
+        }
+
         @Specialization
         @TruffleBoundary
         protected Object doFileExists(RAbstractStringVector vec) {
@@ -547,10 +555,6 @@ public class FileFunctions {
             return RDataFactory.createLogicalVector(status, RDataFactory.COMPLETE_VECTOR);
         }
 
-        @Fallback
-        protected Object doFileExists(@SuppressWarnings("unused") Object vec) {
-            throw RError.error(this, RError.Message.INVALID_ARGUMENT, "file");
-        }
     }
 
     // TODO Implement all the options
@@ -559,17 +563,31 @@ public class FileFunctions {
         private static final String DOT = ".";
         private static final String DOTDOT = "..";
 
+        @Override
+        protected void createCasts(CastBuilder casts) {
+            casts.arg("path").mustBe(stringValue()).asStringVector();
+            casts.arg("pattern").mustBe(stringValue().or(nullValue()));
+            casts.arg("all.files").asLogicalVector().findFirst().notNA().map(toBoolean());
+            casts.arg("full.names").asLogicalVector().findFirst().notNA().map(toBoolean());
+            casts.arg("recursive").asLogicalVector().findFirst().notNA().map(toBoolean());
+            casts.arg("ignore.case").asLogicalVector().findFirst().notNA().map(toBoolean());
+            casts.arg("include.dirs").asLogicalVector().findFirst().notNA().map(toBoolean());
+            casts.arg("no..").asLogicalVector().findFirst().notNA().map(toBoolean());
+        }
+
         @SuppressWarnings("unused")
         @Specialization
         @TruffleBoundary
-        protected RStringVector doListFiles(RAbstractStringVector vec, RNull patternVec, byte allFiles, byte fullNames, byte recursive, byte ignoreCase, byte includeDirs, byte noDotDot) {
+        protected RStringVector doListFiles(RAbstractStringVector vec, RNull patternVec, boolean allFiles, boolean fullNames, boolean recursive, boolean ignoreCase, boolean includeDirs,
+                        boolean noDotDot) {
             return doListFilesBody(vec, null, allFiles, fullNames, recursive, ignoreCase, includeDirs, noDotDot);
         }
 
         @Specialization
         @TruffleBoundary
-        protected RStringVector doListFiles(RAbstractStringVector vec, RAbstractStringVector patternVec, byte allFiles, byte fullNames, byte recursive, byte ignoreCase, byte includeDirs,
-                        byte noDotDot) {
+        protected RStringVector doListFiles(RAbstractStringVector vec, RAbstractStringVector patternVec, boolean allFiles, boolean fullNames, boolean recursive, boolean ignoreCase,
+                        boolean includeDirs,
+                        boolean noDotDot) {
             /*
              * Pattern in first element of vector, remaining elements are ignored (as per GnuR).
              * N.B. The pattern matches file names not paths, which means we cannot just use the
@@ -577,20 +595,22 @@ public class FileFunctions {
              */
 
             String pattern = null;
-            if (!(patternVec.getLength() == 0 || patternVec.getDataAt(0).length() == 0)) {
-                pattern = patternVec.getDataAt(0);
+            if (patternVec.getLength() > 0) {
+                if (RRuntime.isNA(patternVec.getDataAt(0))) {
+                    throw RError.error(this, RError.Message.INVALID_ARGUMENT, "pattern");
+                } else {
+                    pattern = patternVec.getDataAt(0);
+                }
             }
+
             return doListFilesBody(vec, pattern, allFiles, fullNames, recursive, ignoreCase, includeDirs, noDotDot);
         }
 
-        private RStringVector doListFilesBody(RAbstractStringVector vec, String patternString, byte allFilesL, byte fullNamesL, byte recursiveL, byte ignoreCaseL, byte includeDirsL, byte noDotDotL) {
-            boolean allFiles = RRuntime.fromLogical(allFilesL);
-            boolean fullNames = RRuntime.fromLogical(fullNamesL);
-            boolean recursive = RRuntime.fromLogical(recursiveL);
+        private RStringVector doListFilesBody(RAbstractStringVector vec, String patternString, boolean allFiles, boolean fullNames, boolean recursive,
+                        boolean ignoreCaseIn, boolean includeDirsIn, boolean noDotDot) {
+            boolean includeDirs = !recursive || includeDirsIn;
             @SuppressWarnings("unused")
-            boolean ignoreCase = check(ignoreCaseL, "ignoreCase");
-            boolean includeDirs = !recursive || RRuntime.fromLogical(includeDirsL);
-            boolean noDotDot = RRuntime.fromLogical(noDotDotL);
+            boolean ignoreCase = check(ignoreCaseIn, "ignoreCase");
             Pattern pattern = patternString == null ? null : Pattern.compile(patternString);
             // Curiously the result is not a vector of same length as the input,
             // as typical for R, but a single vector, which means duplicates may occur
@@ -644,10 +664,10 @@ public class FileFunctions {
                 Arrays.sort(data);
                 return RDataFactory.createStringVector(data, RDataFactory.COMPLETE_VECTOR);
             }
+
         }
 
-        private boolean check(byte valueLogical, String argName) {
-            boolean value = RRuntime.fromLogical(valueLogical);
+        private boolean check(boolean value, String argName) {
             if (value) {
                 RError.warning(this, RError.Message.GENERIC, "'" + argName + "'" + " is not implemented");
             }
@@ -683,13 +703,18 @@ public class FileFunctions {
         }
     }
 
-    @RBuiltin(name = "list.dirs", kind = INTERNAL, parameterNames = {"path", "full.names", "recursive"}, behavior = IO)
+    @RBuiltin(name = "list.dirs", kind = INTERNAL, parameterNames = {"directory", "full.names", "recursive"}, behavior = IO)
     public abstract static class ListDirs extends RBuiltinNode {
+        @Override
+        protected void createCasts(CastBuilder casts) {
+            casts.arg("directory").mustBe(stringValue()).asStringVector();
+            casts.arg("full.names").asLogicalVector().findFirst().notNA().map(toBoolean());
+            casts.arg("recursive").asLogicalVector().findFirst().notNA().map(toBoolean());
+        }
+
         @Specialization
         @TruffleBoundary
-        protected RStringVector listDirs(RAbstractStringVector paths, byte fullNamesL, byte recursiveL) {
-            boolean fullNames = RRuntime.fromLogical(fullNamesL);
-            boolean recursive = RRuntime.fromLogical(recursiveL);
+        protected RStringVector listDirs(RAbstractStringVector paths, boolean fullNames, boolean recursive) {
             ArrayList<String> dirList = new ArrayList<>();
             for (int i = 0; i < paths.getLength(); i++) {
                 String vecPathString = paths.getDataAt(i);
@@ -736,6 +761,12 @@ public class FileFunctions {
     @RBuiltin(name = "file.path", kind = INTERNAL, parameterNames = {"paths", "fsep"}, behavior = IO)
     public abstract static class FilePath extends RBuiltinNode {
 
+        @Override
+        protected void createCasts(CastBuilder casts) {
+            casts.arg("paths").mustBe(instanceOf(RList.class), RError.Message.INVALID_FIRST_ARGUMENT);
+            casts.arg("fsep").mustBe(stringValue()).asStringVector().findFirst().notNA();
+        }
+
         @Child private CastStringNode castStringNode;
 
         private CastStringNode initCastStringNode() {
@@ -749,12 +780,12 @@ public class FileFunctions {
         @SuppressWarnings("unused")
         @Specialization(guards = "lengthZero(vec)")
         @TruffleBoundary
-        protected RStringVector doFilePathZero(RList vec, RAbstractStringVector fsep) {
+        protected RStringVector doFilePathZero(RList vec, String fsep) {
             return RDataFactory.createEmptyStringVector();
         }
 
         @Specialization(guards = "!lengthZero(args)")
-        protected RStringVector doFilePath(RList args, RAbstractStringVector fsepVec) {
+        protected RStringVector doFilePath(RList args, String fsep) {
             Object[] argValues = args.getDataWithoutCopying();
             int resultLength = 0;
             for (int i = 0; i < argValues.length; i++) {
@@ -775,19 +806,24 @@ public class FileFunctions {
             String[] result = new String[resultLength];
             String[][] inputs = new String[argValues.length][];
             for (int i = 0; i < argValues.length; i++) {
-                Object elem = argValues[i];
-                if (!(elem instanceof String || elem instanceof RStringVector)) {
-                    elem = initCastStringNode().executeString(elem);
+                Object elem = args.getDataAt(i);
+                if (elem instanceof RTypedValue && ((RTypedValue) elem).isS4()) {
+                    throw RError.nyi(this, "list files: S4 elem");
+                } else if (elem instanceof RSymbol) {
+                    inputs[i] = new String[]{((RSymbol) elem).getName()};
+                } else {
+                    if (!(elem instanceof String || elem instanceof RStringVector)) {
+                        elem = initCastStringNode().executeString(elem);
+                    }
                 }
                 if (elem instanceof String) {
                     inputs[i] = new String[]{(String) elem};
                 } else if (elem instanceof RStringVector) {
                     inputs[i] = ((RStringVector) elem).getDataWithoutCopying();
                 } else {
-                    RInternalError.shouldNotReachHere();
+                    throw RError.error(this, RError.Message.NON_STRING_ARG_TO_INTERNAL_PASTE);
                 }
             }
-            String fsep = fsepVec.getDataAt(0);
             for (int i = 0; i < resultLength; i++) {
                 String path = "";
                 for (int j = 0; j < inputs.length; j++) {
@@ -826,20 +862,18 @@ public class FileFunctions {
 
         @Override
         protected void createCasts(CastBuilder casts) {
-            casts.toLogical(2).toLogical(3).toLogical(4).toLogical(5);
-        }
-
-        private boolean checkLogical(byte value, String name) throws RError {
-            if (RRuntime.isNA(value)) {
-                throw RError.error(this, RError.Message.INVALID_ARGUMENT, name);
-            } else {
-                return RRuntime.fromLogical(value);
-            }
+            casts.arg("from").mustBe(stringValue()).asStringVector();
+            casts.arg("to").mustBe(stringValue()).asStringVector();
+            casts.arg("overwrite").asLogicalVector().findFirst().notNA().map(toBoolean());
+            casts.arg("recursive").asLogicalVector().findFirst().notNA().map(toBoolean());
+            casts.arg("copy.mode").asLogicalVector().findFirst().notNA().map(toBoolean());
+            casts.arg("copy.date").asLogicalVector().findFirst().notNA().map(toBoolean());
         }
 
         @Specialization
         @TruffleBoundary
-        protected RLogicalVector fileCopy(RAbstractStringVector vecFrom, RAbstractStringVector vecTo, byte overwriteArg, byte recursiveArg, byte copyModeArg, byte copyDateArg) {
+        protected RLogicalVector fileCopy(RAbstractStringVector vecFrom, RAbstractStringVector vecTo, boolean overwrite, boolean recursiveA, boolean copyMode, boolean copyDate) {
+            boolean recursive = recursiveA;
             int lenFrom = vecFrom.getLength();
             byte[] status = new byte[lenFrom];
             if (lenFrom > 0) {
@@ -847,22 +881,18 @@ public class FileFunctions {
                 if (lenTo != 1) {
                     throw RError.error(this, RError.Message.INVALID_ARGUMENT, "to");
                 }
-                boolean overWrite = checkLogical(overwriteArg, "overwrite");
-                boolean recursive = checkLogical(recursiveArg, "recursive");
-                boolean copyMode = checkLogical(copyModeArg, "copy.mode");
-                boolean copyDate = checkLogical(copyDateArg, "copy.dates");
 
                 // Java cannot distinguish copy.mode and copy.dates
                 CopyOption[] copyOptions;
                 if (copyMode || copyDate) {
-                    copyOptions = new CopyOption[overWrite ? 2 : 1];
-                    copyOptions[overWrite ? 1 : 0] = StandardCopyOption.COPY_ATTRIBUTES;
-                } else if (overWrite) {
+                    copyOptions = new CopyOption[overwrite ? 2 : 1];
+                    copyOptions[overwrite ? 1 : 0] = StandardCopyOption.COPY_ATTRIBUTES;
+                } else if (overwrite) {
                     copyOptions = new CopyOption[1];
                 } else {
                     copyOptions = new CopyOption[0];
                 }
-                if (overWrite) {
+                if (overwrite) {
                     copyOptions[0] = StandardCopyOption.REPLACE_EXISTING;
                 }
                 FileSystem fileSystem = FileSystems.getDefault();
@@ -899,10 +929,10 @@ public class FileFunctions {
                             }
                         } else {
                             // copy to existing files is skipped unless overWrite
-                            if (!Files.exists(toPath) || overWrite) {
+                            if (!Files.exists(toPath) || overwrite) {
                                 /*
-                                 * Be careful if toPath is a directory, if empty Java will replace
-                                 * it with a plain file, otherwise the copy will fail
+                                 * toB Be careful if toPath is a directory, if empty Java will
+                                 * replace it with a plain file, otherwise the copy will fail
                                  */
                                 if (Files.isDirectory(toPath)) {
                                     Path fromFileNamePath = fromPath.getFileName();
@@ -985,6 +1015,11 @@ public class FileFunctions {
 
     @RBuiltin(name = "dirname", kind = INTERNAL, parameterNames = {"path"}, behavior = IO)
     public abstract static class DirName extends XyzNameAdapter {
+        @Override
+        protected void createCasts(CastBuilder casts) {
+            casts.arg("path").mustBe(stringValue(), RError.Message.CHAR_VEC_ARGUMENT);
+        }
+
         @Specialization
         @TruffleBoundary
         protected RStringVector doDirName(RAbstractStringVector vec) {
@@ -998,6 +1033,12 @@ public class FileFunctions {
 
     @RBuiltin(name = "basename", kind = INTERNAL, parameterNames = {"path"}, behavior = IO)
     public abstract static class BaseName extends XyzNameAdapter {
+
+        @Override
+        protected void createCasts(CastBuilder casts) {
+            casts.arg("path").mustBe(stringValue(), RError.Message.CHAR_VEC_ARGUMENT);
+        }
+
         @Specialization
         @TruffleBoundary
         protected RStringVector doDirName(RAbstractStringVector vec) {
@@ -1014,23 +1055,14 @@ public class FileFunctions {
 
         @Override
         protected void createCasts(CastBuilder casts) {
-            casts.toLogical(1).toLogical(2);
-        }
-
-        private boolean checkLogical(byte value, String name) throws RError {
-            if (RRuntime.isNA(value)) {
-                throw RError.error(this, RError.Message.INVALID_ARGUMENT, name);
-            } else {
-                return RRuntime.fromLogical(value);
-            }
+            casts.arg("x").mustBe(stringValue(), RError.Message.CHAR_VEC_ARGUMENT);
+            casts.arg("recursive").asLogicalVector().findFirst().notNA().map(toBoolean());
+            casts.arg("force").asLogicalVector().findFirst().notNA().map(toBoolean());
         }
 
         @Specialization
         @TruffleBoundary
-        protected int doUnlink(RAbstractStringVector vec, byte recursiveArg, byte forceArg) {
-            @SuppressWarnings("unused")
-            boolean force = checkLogical(forceArg, "force");
-            boolean recursive = checkLogical(recursiveArg, "recursive");
+        protected int doUnlink(RAbstractStringVector vec, boolean recursive, @SuppressWarnings("unused") boolean force) {
             int result = 1;
             FileSystem fileSystem = FileSystems.getDefault();
             for (int i = -0; i < vec.getLength(); i++) {
@@ -1087,37 +1119,39 @@ public class FileFunctions {
 
         }
 
-        @SuppressWarnings("unused")
-        @Fallback
-        protected int doUnlink(Object vec, Object recursive, Object force) {
-            throw RError.nyi(this, "unlink");
-        }
-
-        public static boolean simpleArgs(@SuppressWarnings("unused") RAbstractStringVector vec, byte recursive, byte force) {
-            return recursive == RRuntime.LOGICAL_FALSE && force == RRuntime.LOGICAL_FALSE;
-        }
     }
 
     @RBuiltin(name = "dir.create", visibility = OFF, kind = INTERNAL, parameterNames = {"path", "showWarnings", "recursive", "mode"}, behavior = IO)
     public abstract static class DirCreate extends RBuiltinNode {
+
+        @Override
+        protected void createCasts(CastBuilder casts) {
+            casts.arg("path").mustBe(stringValue()).asStringVector().mustBe(size(1)).findFirst();
+            casts.arg("showWarnings").asLogicalVector().findFirst().map(toBoolean());
+            casts.arg("recursive").asLogicalVector().findFirst().map(toBoolean());
+            casts.arg("mode").asIntegerVector().findFirst().mapIf(intNA(), constant(0777));
+        }
+
         @Specialization
         @TruffleBoundary
-        protected byte dirCreate(RAbstractStringVector pathVec, byte showWarnings, byte recursive, RIntVector octMode) {
-            boolean ok = true;
-            if (pathVec.getLength() != 1) {
-                throw RError.error(this, RError.Message.INVALID_ARGUMENT, "path");
-            }
-            String path = Utils.tildeExpand(pathVec.getDataAt(0));
-            if (RRuntime.fromLogical(recursive)) {
-                ok = mkparentdirs(new File(path).getAbsoluteFile().getParentFile(), showWarnings, octMode.getDataAt(0));
-            }
-            if (ok) {
-                ok = mkdir(path, showWarnings, octMode.getDataAt(0));
+        protected byte dirCreate(String pathIn, boolean showWarnings, boolean recursive, int octMode) {
+            boolean ok;
+            if (RRuntime.isNA(pathIn)) {
+                ok = false;
+            } else {
+                ok = true;
+                String path = Utils.tildeExpand(pathIn);
+                if (recursive) {
+                    ok = mkparentdirs(new File(path).getAbsoluteFile().getParentFile(), showWarnings, octMode);
+                }
+                if (ok) {
+                    ok = mkdir(path, showWarnings, octMode);
+                }
             }
             return RRuntime.asLogical(ok);
         }
 
-        private boolean mkparentdirs(File file, byte showWarnings, int mode) {
+        private boolean mkparentdirs(File file, boolean showWarnings, int mode) {
             if (file.isDirectory()) {
                 return true;
             }
@@ -1131,12 +1165,12 @@ public class FileFunctions {
             }
         }
 
-        private boolean mkdir(String path, byte showWarnings, int mode) {
+        private boolean mkdir(String path, boolean showWarnings, int mode) {
             try {
                 RFFIFactory.getRFFI().getBaseRFFI().mkdir(path, mode);
                 return true;
             } catch (IOException ex) {
-                if (RRuntime.fromLogical(showWarnings)) {
+                if (showWarnings) {
                     RError.warning(this, RError.Message.DIR_CANNOT_CREATE, path);
                 }
                 return false;
@@ -1146,6 +1180,11 @@ public class FileFunctions {
 
     @RBuiltin(name = "dir.exists", kind = INTERNAL, parameterNames = "paths", behavior = IO)
     public abstract static class DirExists extends RBuiltinNode {
+        @Override
+        protected void createCasts(CastBuilder casts) {
+            casts.arg("paths").mustBe(stringValue()).asStringVector();
+        }
+
         @Specialization
         @TruffleBoundary
         protected RLogicalVector dirExists(RAbstractStringVector pathVec) {
@@ -1158,9 +1197,5 @@ public class FileFunctions {
             return RDataFactory.createLogicalVector(data, RDataFactory.COMPLETE_VECTOR);
         }
 
-        @Fallback
-        protected RLogicalVector dirExists(@SuppressWarnings("unused") Object pathVec) {
-            throw RError.error(this, RError.Message.INVALID_ARGUMENT, "filename");
-        }
     }
 }
diff --git a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/LoadSaveFunctions.java b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/LoadSaveFunctions.java
index e61ffdd09d51f9b01e722c6b7b567781c44514dd..34351b6c07a807136dd00d26596f14eda374d5a0 100644
--- a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/LoadSaveFunctions.java
+++ b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/LoadSaveFunctions.java
@@ -12,6 +12,7 @@
  */
 package com.oracle.truffle.r.nodes.builtin.base;
 
+import static com.oracle.truffle.r.nodes.builtin.CastBuilder.Predef.*;
 import static com.oracle.truffle.r.runtime.RVisibility.OFF;
 import static com.oracle.truffle.r.runtime.builtins.RBehavior.IO;
 import static com.oracle.truffle.r.runtime.builtins.RBuiltinKind.INTERNAL;
@@ -25,6 +26,7 @@ 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.frame.VirtualFrame;
+import com.oracle.truffle.r.nodes.builtin.CastBuilder;
 import com.oracle.truffle.r.nodes.builtin.RBuiltinNode;
 import com.oracle.truffle.r.nodes.builtin.base.SerializeFunctions.Adapter;
 import com.oracle.truffle.r.nodes.function.PromiseHelperNode.PromiseCheckHelperNode;
@@ -38,7 +40,6 @@ import com.oracle.truffle.r.runtime.data.RDataFactory;
 import com.oracle.truffle.r.runtime.data.RNull;
 import com.oracle.truffle.r.runtime.data.RPairList;
 import com.oracle.truffle.r.runtime.data.RStringVector;
-import com.oracle.truffle.r.runtime.data.model.RAbstractLogicalVector;
 import com.oracle.truffle.r.runtime.data.model.RAbstractStringVector;
 import com.oracle.truffle.r.runtime.env.REnvironment;
 import com.oracle.truffle.r.runtime.env.REnvironment.PutException;
@@ -53,9 +54,16 @@ public class LoadSaveFunctions {
 
         private final NACheck naCheck = NACheck.create();
 
+        @Override
+        protected void createCasts(CastBuilder casts) {
+            casts.arg("con").mustBe(instanceOf(RConnection.class));
+            casts.arg("envir").mustBe(nullValue().not(), RError.Message.USE_NULL_ENV_DEFUNCT).mustBe(instanceOf(REnvironment.class));
+            casts.arg("verbose").asLogicalVector().findFirst().map(toBoolean());
+        }
+
         @Specialization
         @TruffleBoundary
-        protected RStringVector load(RConnection con, REnvironment envir, @SuppressWarnings("unused") RAbstractLogicalVector verbose) {
+        protected RStringVector load(RConnection con, REnvironment envir, @SuppressWarnings("unused") boolean verbose) {
             try (RConnection openConn = con.forceOpen("r")) {
                 String s = openConn.readChar(5, true);
                 if (s.equals("RDA2\n") || s.equals("RDB2\n") || s.equals("RDX2\n")) {
@@ -98,10 +106,16 @@ public class LoadSaveFunctions {
         }
     }
 
-    @RBuiltin(name = "load", visibility = OFF, kind = INTERNAL, parameterNames = {"con", "envir"}, behavior = IO)
+    @RBuiltin(name = "load", visibility = OFF, kind = INTERNAL, parameterNames = {"file", "envir"}, behavior = IO)
     public abstract static class Load extends RBuiltinNode {
         // now deprecated but still used by some packages
 
+        @Override
+        protected void createCasts(CastBuilder casts) {
+            casts.arg("file").mustBe(stringValue()).asStringVector().mustBe(notEmpty(), RError.Message.FIRST_ARGUMENT_NOT_FILENAME).findFirst();
+            casts.arg("envir").mustBe(nullValue().not(), RError.Message.USE_NULL_ENV_DEFUNCT).mustBe(instanceOf(REnvironment.class));
+        }
+
         private static final int R_MAGIC_EMPTY = 999;
         private static final int R_MAGIC_CORRUPT = 998;
         private static final int R_MAGIC_TOONEW = 997;
@@ -114,8 +128,8 @@ public class LoadSaveFunctions {
 
         @Specialization
         @TruffleBoundary
-        protected RStringVector load(RAbstractStringVector fileVec, @SuppressWarnings("unused") REnvironment envir) {
-            String path = Utils.tildeExpand(fileVec.getDataAt(0));
+        protected RStringVector load(String pathIn, @SuppressWarnings("unused") REnvironment envir) {
+            String path = Utils.tildeExpand(pathIn);
             try (BufferedInputStream bs = new BufferedInputStream(new FileInputStream(path))) {
                 int magic = readMagic(bs);
                 switch (magic) {
@@ -169,16 +183,25 @@ public class LoadSaveFunctions {
         }
     }
 
-    @RBuiltin(name = "saveToConn", visibility = OFF, kind = INTERNAL, parameterNames = {"list", "conn", "ascii", "version", "envir", "eval.promises"}, behavior = IO)
+    @RBuiltin(name = "saveToConn", visibility = OFF, kind = INTERNAL, parameterNames = {"list", "con", "ascii", "version", "environment", "eval.promises"}, behavior = IO)
     public abstract static class SaveToConn extends Adapter {
         private static final String ASCII_HEADER = "RDA2\n";
         private static final String XDR_HEADER = "RDX2\n";
 
+        @Override
+        protected void createCasts(CastBuilder casts) {
+            casts.arg("list").mustBe(stringValue()).asStringVector().mustBe(notEmpty(), RError.Message.FIRST_ARGUMENT_NOT_CHARVEC).findFirst();
+            casts.arg("con").mustBe(instanceOf(RConnection.class));
+            casts.arg("ascii").mustBe(logicalValue(), RError.Message.ASCII_NOT_LOGICAL);
+            casts.arg("version").mustBe(nullValue().or(integerValue()));
+            casts.arg("environment").mustBe(nullValue().not(), RError.Message.USE_NULL_ENV_DEFUNCT).mustBe(instanceOf(REnvironment.class));
+            casts.arg("eval.promises").asLogicalVector().findFirst().notNA().map(toBoolean());
+        }
+
         @Specialization
         protected Object saveToConn(VirtualFrame frame, RAbstractStringVector list, RConnection conn, byte asciiLogical, @SuppressWarnings("unused") RNull version, REnvironment envir,
-                        byte evalPromisesLogical, //
+                        boolean evalPromises, //
                         @Cached("new()") PromiseCheckHelperNode promiseHelper) {
-            boolean evalPromises = RRuntime.fromLogical(evalPromisesLogical);
             RPairList prev = null;
             Object toSave = RNull.instance;
             for (int i = 0; i < list.getLength(); i++) {
diff --git a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/NamespaceFunctions.java b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/NamespaceFunctions.java
index 9c70a9bdcc45b919cfb1bdf2a8e00c786eeaba86..a0b4cfd5a48eea7bfa58e5b79049b9f426a83916 100644
--- a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/NamespaceFunctions.java
+++ b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/NamespaceFunctions.java
@@ -22,11 +22,13 @@
  */
 package com.oracle.truffle.r.nodes.builtin.base;
 
+import static com.oracle.truffle.r.nodes.builtin.CastBuilder.Predef.*;
 import static com.oracle.truffle.r.runtime.builtins.RBehavior.MODIFIES_STATE;
 import static com.oracle.truffle.r.runtime.builtins.RBehavior.PURE;
 import static com.oracle.truffle.r.runtime.builtins.RBehavior.READS_STATE;
 import static com.oracle.truffle.r.runtime.builtins.RBuiltinKind.INTERNAL;
 
+import com.oracle.truffle.api.dsl.Fallback;
 import com.oracle.truffle.api.dsl.Specialization;
 import com.oracle.truffle.r.nodes.builtin.CastBuilder;
 import com.oracle.truffle.r.nodes.builtin.RBuiltinNode;
@@ -40,8 +42,19 @@ import com.oracle.truffle.r.runtime.env.REnvironment;
 
 public class NamespaceFunctions {
 
+    private abstract static class CastHelper extends RBuiltinNode {
+        protected void name(CastBuilder casts) {
+            casts.arg("name").mustBe(stringValue().or(instanceOf(RSymbol.class)));
+        }
+    }
+
     @RBuiltin(name = "getRegisteredNamespace", kind = INTERNAL, parameterNames = {"name"}, behavior = READS_STATE)
-    public abstract static class GetRegisteredNamespace extends RBuiltinNode {
+    public abstract static class GetRegisteredNamespace extends CastHelper {
+        @Override
+        protected void createCasts(CastBuilder casts) {
+            name(casts);
+        }
+
         @Specialization
         protected Object doGetRegisteredNamespace(RAbstractStringVector name) {
             Object result = REnvironment.getRegisteredNamespace(name.getDataAt(0));
@@ -64,7 +77,12 @@ public class NamespaceFunctions {
     }
 
     @RBuiltin(name = "isRegisteredNamespace", kind = INTERNAL, parameterNames = {"name"}, behavior = READS_STATE)
-    public abstract static class IsRegisteredNamespace extends RBuiltinNode {
+    public abstract static class IsRegisteredNamespace extends CastHelper {
+        @Override
+        protected void createCasts(CastBuilder casts) {
+            name(casts);
+        }
+
         @Specialization
         protected byte doIsRegisteredNamespace(RAbstractStringVector name) {
             Object result = REnvironment.getRegisteredNamespace(name.getDataAt(0));
@@ -93,8 +111,8 @@ public class NamespaceFunctions {
             return RRuntime.asLogical(env.isNamespaceEnv());
         }
 
-        @Specialization
-        protected byte doIsNamespaceEnv(@SuppressWarnings("unused") RNull env) {
+        @Fallback
+        protected byte doIsNamespaceEnv(@SuppressWarnings("unused") Object env) {
             return RRuntime.LOGICAL_FALSE;
         }
     }
@@ -108,23 +126,38 @@ public class NamespaceFunctions {
     }
 
     @RBuiltin(name = "registerNamespace", kind = INTERNAL, parameterNames = {"name", "env"}, behavior = MODIFIES_STATE)
-    public abstract static class RegisterNamespace extends RBuiltinNode {
+    public abstract static class RegisterNamespace extends CastHelper {
         @Override
         protected void createCasts(CastBuilder casts) {
-            casts.arg("name").asStringVector().findFirst();
+            name(casts);
+            casts.arg("env").mustBe(instanceOf(REnvironment.class));
         }
 
         @Specialization
-        protected RNull registerNamespace(String name, REnvironment env) {
-            if (REnvironment.registerNamespace(name, env) == null) {
+        protected RNull registerNamespace(RAbstractStringVector name, REnvironment env) {
+            if (REnvironment.registerNamespace(name.getDataAt(0), env) == null) {
                 throw RError.error(this, RError.Message.NS_ALREADY_REG);
             }
             return RNull.instance;
         }
+
+        @Specialization
+        protected RNull registerNamespace(RSymbol nameSym, REnvironment env) {
+            if (REnvironment.registerNamespace(nameSym.getName(), env) == null) {
+                throw RError.error(this, RError.Message.NS_ALREADY_REG);
+            }
+            return RNull.instance;
+
+        }
     }
 
     @RBuiltin(name = "unregisterNamespace", kind = INTERNAL, parameterNames = {"name"}, behavior = MODIFIES_STATE)
-    public abstract static class UnregisterNamespace extends RBuiltinNode {
+    public abstract static class UnregisterNamespace extends CastHelper {
+        @Override
+        protected void createCasts(CastBuilder casts) {
+            name(casts);
+        }
+
         @Specialization
         protected RNull unregisterNamespace(RAbstractStringVector name) {
             doUnregisterNamespace(name.getDataAt(0));
diff --git a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/NormalizePath.java b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/NormalizePath.java
index 2d0e01271104e3abec2bbb8e8cddf2b318ab955a..9d46b2bb64d65873fe9fe27c21622f061d036dea 100644
--- a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/NormalizePath.java
+++ b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/NormalizePath.java
@@ -85,9 +85,4 @@ public abstract class NormalizePath extends RBuiltinNode {
         return RDataFactory.createStringVector(results, RDataFactory.COMPLETE_VECTOR);
     }
 
-    @SuppressWarnings("unused")
-    @Specialization
-    protected Object doNormalizePath(Object path, Object winslash, Object mustWork) {
-        throw RError.error(this, RError.Message.WRONG_TYPE);
-    }
 }
diff --git a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/Quit.java b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/Quit.java
index 17aa680ce81c3782274c132ced48f1b299217f6d..7ccf2fb1894bc50ef24ca7f765e3913e03b10cea 100644
--- a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/Quit.java
+++ b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/Quit.java
@@ -12,12 +12,12 @@
  */
 package com.oracle.truffle.r.nodes.builtin.base;
 
+import static com.oracle.truffle.r.nodes.builtin.CastBuilder.Predef.*;
 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;
 
 import com.oracle.truffle.api.CompilerDirectives.TruffleBoundary;
-import com.oracle.truffle.api.dsl.Fallback;
 import com.oracle.truffle.api.dsl.Specialization;
 import com.oracle.truffle.r.nodes.builtin.CastBuilder;
 import com.oracle.truffle.r.nodes.builtin.RBuiltinNode;
@@ -30,14 +30,15 @@ import com.oracle.truffle.r.runtime.RStartParams.SA_TYPE;
 import com.oracle.truffle.r.runtime.builtins.RBuiltin;
 import com.oracle.truffle.r.runtime.context.RContext;
 import com.oracle.truffle.r.runtime.data.RNull;
-import com.oracle.truffle.r.runtime.data.model.RAbstractStringVector;
 
 @RBuiltin(name = "quit", visibility = OFF, kind = INTERNAL, parameterNames = {"save", "status", "runLast"}, behavior = COMPLEX)
 public abstract class Quit extends RBuiltinNode {
 
     @Override
     protected void createCasts(CastBuilder casts) {
-        casts.toInteger(1);
+        casts.arg("save").mustBe(stringValue(), RError.Message.QUIT_ASK).asStringVector().findFirst();
+        casts.arg("status").asIntegerVector().findFirst();
+        casts.arg("runLast").asLogicalVector().findFirst();
     }
 
     private SA_TYPE checkSaveValue(String save) throws RError {
@@ -51,20 +52,20 @@ public abstract class Quit extends RBuiltinNode {
 
     @Specialization
     @TruffleBoundary
-    protected Object doQuit(RAbstractStringVector saveArg, final int status, final byte runLastIn) {
+    protected Object doQuit(String save, final int status, final byte runLastIn) {
+        byte runLast = runLastIn;
         if (RContext.getInstance().stateInstrumentation.getBrowserState().inBrowser()) {
             RError.warning(this, RError.Message.BROWSER_QUIT);
             return RNull.instance;
         }
-        String save = saveArg.getDataAt(0);
         RStartParams.SA_TYPE ask = checkSaveValue(save);
         if (ask == SA_TYPE.SAVEASK && !RContext.getInstance().getConsoleHandler().isInteractive()) {
             RError.warning(this, RError.Message.QUIT_ASK_INTERACTIVE);
         }
         if (status == RRuntime.INT_NA) {
             RError.warning(this, RError.Message.QUIT_INVALID_STATUS);
+            runLast = RRuntime.LOGICAL_FALSE;
         }
-        byte runLast = runLastIn;
         if (runLast == RRuntime.LOGICAL_NA) {
             RError.warning(this, RError.Message.QUIT_INVALID_RUNLAST);
             runLast = RRuntime.LOGICAL_FALSE;
@@ -73,12 +74,4 @@ public abstract class Quit extends RBuiltinNode {
         throw RInternalError.shouldNotReachHere("cleanup returned");
     }
 
-    @SuppressWarnings("unused")
-    @Fallback
-    protected Object doQuit(Object saveArg, Object status, Object runLast) {
-        if (RRuntime.asString(saveArg) == null) {
-            throw RError.error(this, RError.Message.QUIT_ASK);
-        }
-        throw RError.error(this, RError.Message.INVALID_OR_UNIMPLEMENTED_ARGUMENTS);
-    }
 }
diff --git a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/RegFinalizer.java b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/RegFinalizer.java
index 03395b1cca29c625d320395c1cac8ada93948329..0eeca3ebde014c43f4bbca7a83b788c7360614ba 100644
--- a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/RegFinalizer.java
+++ b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/RegFinalizer.java
@@ -22,14 +22,14 @@
  */
 package com.oracle.truffle.r.nodes.builtin.base;
 
+import static com.oracle.truffle.r.nodes.builtin.CastBuilder.Predef.*;
 import static com.oracle.truffle.r.runtime.builtins.RBehavior.COMPLEX;
 import static com.oracle.truffle.r.runtime.builtins.RBuiltinKind.INTERNAL;
 
-import com.oracle.truffle.api.dsl.Fallback;
 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.RExternalPtr;
 import com.oracle.truffle.r.runtime.data.RFunction;
@@ -38,31 +38,27 @@ import com.oracle.truffle.r.runtime.env.REnvironment;
 
 @RBuiltin(name = "reg.finalizer", kind = INTERNAL, parameterNames = {"e", "f", "onexit"}, behavior = COMPLEX)
 public abstract class RegFinalizer extends RBuiltinNode {
+    @Override
+    protected void createCasts(CastBuilder casts) {
+        casts.arg("e").mustBe(instanceOf(REnvironment.class).or(instanceOf(RExternalPtr.class)), RError.Message.REG_FINALIZER_FIRST);
+        casts.arg("f").mustBe(instanceOf(RFunction.class), RError.Message.REG_FINALIZER_SECOND);
+        casts.arg("onexit").asLogicalVector().findFirst().notNA(RError.Message.REG_FINALIZER_THIRD).map(toBoolean());
+    }
+
     @Specialization
-    protected RNull doRegFinalizer(RExternalPtr ext, RFunction fun, byte onexit) {
+    protected RNull doRegFinalizer(RExternalPtr ext, RFunction fun, boolean onexit) {
         return doRegFinalizerEither(ext, fun, onexit);
     }
 
     @Specialization
-    protected RNull doRegFinalizer(REnvironment env, RFunction fun, byte onexit) {
+    protected RNull doRegFinalizer(REnvironment env, RFunction fun, boolean onexit) {
         return doRegFinalizerEither(env, fun, onexit);
     }
 
     @SuppressWarnings("unused")
-    private RNull doRegFinalizerEither(Object env, RFunction fun, byte onexit) {
-        if (onexit == RRuntime.LOGICAL_NA) {
-            throw RError.error(this, RError.Message.REG_FINALIZER_THIRD);
-        }
+    private static RNull doRegFinalizerEither(Object env, RFunction fun, boolean onexit) {
         // TODO the actual work
         return RNull.instance;
     }
 
-    @SuppressWarnings("unused")
-    @Fallback
-    protected RNull doRegFinalizer(Object env, Object fun, byte onexit) {
-        if (fun instanceof RFunction) {
-            throw RError.error(this, RError.Message.REG_FINALIZER_FIRST);
-        }
-        throw RError.error(this, RError.Message.REG_FINALIZER_SECOND);
-    }
 }
diff --git a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/SerializeFunctions.java b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/SerializeFunctions.java
index a4b3465b43cfc0d321fae8473efa1d4092d56249..438c5855bb4d37494b43dd47f8250e13e9385094 100644
--- a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/SerializeFunctions.java
+++ b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/SerializeFunctions.java
@@ -22,6 +22,7 @@
  */
 package com.oracle.truffle.r.nodes.builtin.base;
 
+import static com.oracle.truffle.r.nodes.builtin.CastBuilder.Predef.*;
 import static com.oracle.truffle.r.runtime.RVisibility.OFF;
 import static com.oracle.truffle.r.runtime.builtins.RBehavior.IO;
 import static com.oracle.truffle.r.runtime.builtins.RBuiltinKind.INTERNAL;
@@ -29,8 +30,8 @@ import static com.oracle.truffle.r.runtime.builtins.RBuiltinKind.INTERNAL;
 import java.io.IOException;
 
 import com.oracle.truffle.api.CompilerDirectives.TruffleBoundary;
-import com.oracle.truffle.api.dsl.Fallback;
 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;
@@ -80,10 +81,19 @@ public class SerializeFunctions {
                 throw RError.error(this, RError.Message.GENERIC, ex.getMessage());
             }
         }
+
+        protected void connection(CastBuilder casts) {
+            casts.arg("con").mustBe(instanceOf(RConnection.class));
+        }
     }
 
-    @RBuiltin(name = "unserializeFromConn", kind = INTERNAL, parameterNames = {"conn", "refhook"}, behavior = IO)
+    @RBuiltin(name = "unserializeFromConn", kind = INTERNAL, parameterNames = {"con", "refhook"}, behavior = IO)
     public abstract static class UnserializeFromConn extends Adapter {
+        @Override
+        protected void createCasts(CastBuilder casts) {
+            connection(casts);
+        }
+
         @Specialization
         protected Object doUnserializeFromConn(RConnection conn, @SuppressWarnings("unused") RNull refhook) {
             return doUnserializeFromConnBase(conn, null);
@@ -96,8 +106,15 @@ public class SerializeFunctions {
         }
     }
 
-    @RBuiltin(name = "serializeToConn", visibility = OFF, kind = INTERNAL, parameterNames = {"object", "conn", "ascii", "version", "refhook"}, behavior = IO)
+    @RBuiltin(name = "serializeToConn", visibility = OFF, kind = INTERNAL, parameterNames = {"object", "con", "ascii", "version", "refhook"}, behavior = IO)
     public abstract static class SerializeToConn extends Adapter {
+        @Override
+        protected void createCasts(CastBuilder casts) {
+            connection(casts);
+            casts.arg("ascii").mustBe(logicalValue(), RError.Message.ASCII_NOT_LOGICAL);
+            casts.arg("version").mustBe(nullValue().or(integerValue()));
+        }
+
         @Specialization
         protected Object doSerializeToConn(Object object, RConnection conn, byte asciiLogical, RNull version, RNull refhook) {
             int type;
@@ -112,8 +129,13 @@ public class SerializeFunctions {
         }
     }
 
-    @RBuiltin(name = "unserialize", kind = INTERNAL, parameterNames = {"conn", "refhook"}, behavior = IO)
+    @RBuiltin(name = "unserialize", kind = INTERNAL, parameterNames = {"con", "refhook"}, behavior = IO)
     public abstract static class Unserialize extends Adapter {
+        @Override
+        protected void createCasts(CastBuilder casts) {
+            casts.arg("con").mustBe(instanceOf(RConnection.class).or(instanceOf(RAbstractRawVector.class)));
+        }
+
         @Specialization
         protected Object unSerialize(RConnection conn, @SuppressWarnings("unused") RNull refhook) {
             return doUnserializeFromConnBase(conn, null);
@@ -125,8 +147,14 @@ public class SerializeFunctions {
         }
     }
 
-    @RBuiltin(name = "serialize", kind = INTERNAL, parameterNames = {"object", "conn", "type", "version", "refhook"}, behavior = IO)
+    @RBuiltin(name = "serialize", kind = INTERNAL, parameterNames = {"object", "con", "type", "version", "refhook"}, behavior = IO)
     public abstract static class Serialize extends Adapter {
+        @Override
+        protected void createCasts(CastBuilder casts) {
+            casts.arg("con").mustBe(nullValue().or(instanceOf(RConnection.class)));
+            casts.arg("type").asIntegerVector().findFirst();
+        }
+
         @Specialization
         protected Object serialize(Object object, RConnection conn, int type, RNull version, RNull refhook) {
             return doSerializeToConnBase(object, conn, type, RRuntime.LOGICAL_NA, version, refhook);
@@ -139,15 +167,16 @@ public class SerializeFunctions {
             return RDataFactory.createRawVector(data);
         }
 
-        @SuppressWarnings("unused")
-        @Fallback
-        protected Object serialize(Object object, Object conn, Object asciiLogical, Object version, Object refhook) {
-            throw RError.error(this, RError.Message.INVALID_OR_UNIMPLEMENTED_ARGUMENTS);
-        }
     }
 
-    @RBuiltin(name = "serializeb", kind = INTERNAL, parameterNames = {"object", "conn", "xdr", "version", "refhook"}, behavior = IO)
+    @RBuiltin(name = "serializeb", kind = INTERNAL, parameterNames = {"object", "con", "xdr", "version", "refhook"}, behavior = IO)
     public abstract static class SerializeB extends Adapter {
+        @Override
+        protected void createCasts(CastBuilder casts) {
+            connection(casts);
+            casts.arg("xdr").asLogicalVector().findFirst();
+        }
+
         @Specialization
         protected Object serializeB(Object object, RConnection conn, byte xdrLogical, RNull version, RNull refhook) {
             if (!RRuntime.fromLogical(xdrLogical)) {
diff --git a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/SetTimeLimit.java b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/SetTimeLimit.java
index 4eb04d2dfb03d1510bf49fd5581e53c0a29c5027..61e0a0edaf5a66fe8db29e29cfc1ad77115ca4b4 100644
--- a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/SetTimeLimit.java
+++ b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/SetTimeLimit.java
@@ -22,10 +22,12 @@
  */
 package com.oracle.truffle.r.nodes.builtin.base;
 
+import static com.oracle.truffle.r.nodes.builtin.CastBuilder.Predef.*;
 import static com.oracle.truffle.r.runtime.builtins.RBehavior.COMPLEX;
 import static com.oracle.truffle.r.runtime.builtins.RBuiltinKind.INTERNAL;
 
 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.builtins.RBuiltin;
 import com.oracle.truffle.r.runtime.data.RNull;
@@ -33,9 +35,16 @@ import com.oracle.truffle.r.runtime.data.RNull;
 @RBuiltin(name = "setTimeLimit", kind = INTERNAL, parameterNames = {"cpu", "elapsed", "transient"}, behavior = COMPLEX)
 public abstract class SetTimeLimit extends RBuiltinNode {
 
+    @Override
+    protected void createCasts(CastBuilder casts) {
+        casts.arg("cpu").asDoubleVector().findFirst();
+        casts.arg("elapsed").asDoubleVector().findFirst();
+        casts.arg("transient").asLogicalVector().findFirst().map(toBoolean());
+    }
+
     @SuppressWarnings("unused")
     @Specialization
-    protected RNull setTimeLimit(Object cpu, Object elapsed, Object trans) {
+    protected RNull setTimeLimit(double cpu, double elapsed, boolean trans) {
         // TODO: proper implementation sets timers checked during user interrupts that we currently
         // do not support
         return RNull.instance;
diff --git a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/Stop.java b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/Stop.java
index e8a0c744fb4d30711479e6942e1ad9f3c1b142e7..2cdff7e1f4d1ae7422ac646a0563ef68d7c760b2 100644
--- a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/Stop.java
+++ b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/Stop.java
@@ -22,24 +22,34 @@
  */
 package com.oracle.truffle.r.nodes.builtin.base;
 
+import static com.oracle.truffle.r.nodes.builtin.CastBuilder.Predef.*;
 import static com.oracle.truffle.r.runtime.builtins.RBehavior.COMPLEX;
 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.RRuntime;
 import com.oracle.truffle.r.runtime.builtins.RBuiltin;
-import com.oracle.truffle.r.runtime.data.model.RAbstractStringVector;
+import com.oracle.truffle.r.runtime.data.RNull;
 
-@RBuiltin(name = "stop", kind = INTERNAL, parameterNames = {"call.", "message"}, behavior = COMPLEX)
+@RBuiltin(name = "stop", kind = INTERNAL, parameterNames = {"call", "message"}, behavior = COMPLEX)
 public abstract class Stop extends RBuiltinNode {
+    @Override
+    protected void createCasts(CastBuilder casts) {
+        casts.arg("call").asLogicalVector().findFirst().map(toBoolean());
+        casts.arg("message").mustBe(stringValue().or(nullValue())).asStringVector().mustBe(notEmpty(), RError.Message.INVALID_STRING_IN_STOP).findFirst();
+    }
+
+    @Specialization
+    protected Object stop(boolean call, @SuppressWarnings("unused") RNull msgVec) {
+        throw stop(call, "");
+    }
 
     @Specialization
-    protected Object stop(byte call, RAbstractStringVector msgVec) {
-        assert msgVec.getLength() == 1;
+    protected RError stop(boolean call, String message) throws RError {
         CompilerDirectives.transferToInterpreter();
-        throw RError.stop(RRuntime.fromLogical(call), RError.SHOW_CALLER2, RError.Message.GENERIC, msgVec.getDataAt(0));
+        throw RError.stop(call, RError.SHOW_CALLER2, RError.Message.GENERIC, message);
     }
 }
diff --git a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/SysFunctions.java b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/SysFunctions.java
index c9ec3cf691058f7a0c9b720677fd0a57c8dd58b9..27809328cf707804677a8a357b7ffb30a240fab6 100644
--- a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/SysFunctions.java
+++ b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/SysFunctions.java
@@ -22,6 +22,7 @@
  */
 package com.oracle.truffle.r.nodes.builtin.base;
 
+import static com.oracle.truffle.r.nodes.builtin.CastBuilder.Predef.*;
 import static com.oracle.truffle.r.runtime.RVisibility.CUSTOM;
 import static com.oracle.truffle.r.runtime.RVisibility.OFF;
 import static com.oracle.truffle.r.runtime.builtins.RBehavior.COMPLEX;
@@ -34,13 +35,13 @@ import java.io.IOException;
 import java.util.ArrayList;
 import java.util.Map;
 
-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.frame.Frame;
 import com.oracle.truffle.api.frame.FrameInstance.FrameAccess;
 import com.oracle.truffle.api.frame.VirtualFrame;
 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.RBuiltinPackages;
 import com.oracle.truffle.r.runtime.RArguments;
@@ -64,7 +65,6 @@ public class SysFunctions {
 
     @RBuiltin(name = "Sys.getpid", kind = INTERNAL, parameterNames = {}, behavior = READS_STATE)
     public abstract static class SysGetpid extends RBuiltinNode {
-
         @Specialization
         @TruffleBoundary
         protected Object sysGetPid() {
@@ -77,6 +77,12 @@ public class SysFunctions {
     public abstract static class SysGetenv extends RBuiltinNode {
         private final ConditionProfile zeroLengthProfile = ConditionProfile.createBinaryProfile();
 
+        @Override
+        protected void createCasts(CastBuilder casts) {
+            casts.arg("x").mustBe(stringValue(), RError.Message.ARGUMENT_WRONG_TYPE);
+            casts.arg("unset").mustBe(stringValue()).asStringVector().mustBe(size(1));
+        }
+
         @Specialization
         @TruffleBoundary
         protected Object sysGetEnv(RAbstractStringVector x, RAbstractStringVector unset) {
@@ -110,11 +116,6 @@ public class SysFunctions {
             }
         }
 
-        @Specialization
-        protected Object sysGetEnvGeneric(@SuppressWarnings("unused") Object x, @SuppressWarnings("unused") Object unset) {
-            CompilerDirectives.transferToInterpreter();
-            throw RError.error(this, RError.Message.WRONG_TYPE);
-        }
     }
 
     /**
@@ -138,7 +139,6 @@ public class SysFunctions {
                         // Now we can run the overrides
                         RBuiltinPackages.loadDefaultPackageOverrides(RContext.getInstance().getNamespaceName());
                     }
-                    System.console();
                 }
             }
 
@@ -147,9 +147,17 @@ public class SysFunctions {
 
     @RBuiltin(name = "Sys.setenv", visibility = OFF, kind = INTERNAL, parameterNames = {"nm", "values"}, behavior = MODIFIES_STATE)
     public abstract static class SysSetEnv extends LoadNamespaceAdapter {
+        @Override
+        protected void createCasts(CastBuilder casts) {
+            casts.arg("nm").mustBe(stringValue(), RError.Message.ARGUMENT_WRONG_TYPE);
+            casts.arg("values").mustBe(stringValue(), RError.Message.ARGUMENT_WRONG_TYPE);
+        }
 
         @Specialization
         protected RLogicalVector doSysSetEnv(VirtualFrame frame, RAbstractStringVector names, RAbstractStringVector values) {
+            if (names.getLength() != values.getLength()) {
+                throw RError.error(this, RError.Message.ARGUMENT_WRONG_LENGTH);
+            }
             checkNSLoad(frame, names, values, true);
             return doSysSetEnv(names, values);
         }
@@ -168,6 +176,10 @@ public class SysFunctions {
 
     @RBuiltin(name = "Sys.unsetenv", visibility = OFF, kind = INTERNAL, parameterNames = {"x"}, behavior = READS_STATE)
     public abstract static class SysUnSetEnv extends LoadNamespaceAdapter {
+        @Override
+        protected void createCasts(CastBuilder casts) {
+            casts.arg("x").mustBe(stringValue(), RError.Message.ARGUMENT_WRONG_TYPE);
+        }
 
         @Specialization
         protected RLogicalVector doSysUnSetEnv(VirtualFrame frame, RAbstractStringVector names) {
@@ -189,6 +201,10 @@ public class SysFunctions {
 
     @RBuiltin(name = "Sys.sleep", visibility = OFF, kind = INTERNAL, parameterNames = {"time"}, behavior = COMPLEX)
     public abstract static class SysSleep extends RBuiltinNode {
+        @Override
+        protected void createCasts(CastBuilder casts) {
+            casts.arg("time").asDoubleVector().findFirst().mustBe(gte(0.0).and(eq(Double.NaN).not()));
+        }
 
         @Specialization
         @TruffleBoundary
@@ -197,44 +213,10 @@ public class SysFunctions {
             return RNull.instance;
         }
 
-        @Specialization
-        @TruffleBoundary
-        protected Object sysSleep(String secondsString) {
-            long millis = convertToMillis(checkValidString(secondsString));
-            sleep(millis);
-            return RNull.instance;
-        }
-
-        @Specialization(guards = "lengthOne(secondsVector)")
-        @TruffleBoundary
-        protected Object sysSleep(RStringVector secondsVector) {
-            long millis = convertToMillis(checkValidString(secondsVector.getDataAt(0)));
-            sleep(millis);
-            return RNull.instance;
-        }
-
-        protected static boolean lengthOne(RStringVector vec) {
-            return vec.getLength() == 1;
-        }
-
-        @Specialization
-        @TruffleBoundary
-        protected Object sysSleep(@SuppressWarnings("unused") Object arg) {
-            throw RError.error(this, RError.Message.INVALID_VALUE, "time");
-        }
-
         private static long convertToMillis(double d) {
             return (long) (d * 1000);
         }
 
-        private double checkValidString(String s) {
-            try {
-                return Double.parseDouble(s);
-            } catch (NumberFormatException ex) {
-                throw RError.error(this, RError.Message.INVALID_VALUE, "time");
-            }
-        }
-
         private static void sleep(long millis) {
             try {
                 Thread.sleep(millis);
@@ -249,16 +231,14 @@ public class SysFunctions {
      */
     @RBuiltin(name = "Sys.readlink", kind = INTERNAL, parameterNames = {"paths"}, behavior = IO)
     public abstract static class SysReadlink extends RBuiltinNode {
-
-        @Specialization
-        @TruffleBoundary
-        protected Object sysReadlink(String path) {
-            return RDataFactory.createStringVector(doSysReadLink(path));
+        @Override
+        protected void createCasts(CastBuilder casts) {
+            casts.arg("paths").mustBe(stringValue());
         }
 
         @Specialization
         @TruffleBoundary
-        protected Object sysReadlink(RStringVector vector) {
+        protected Object sysReadlink(RAbstractStringVector vector) {
             String[] paths = new String[vector.getLength()];
             boolean complete = RDataFactory.COMPLETE_VECTOR;
             for (int i = 0; i < paths.length; i++) {
@@ -289,19 +269,20 @@ public class SysFunctions {
             return s;
         }
 
-        @Specialization
-        protected Object sysReadlinkGeneric(@SuppressWarnings("unused") Object path) {
-            CompilerDirectives.transferToInterpreter();
-            throw RError.error(this, RError.Message.INVALID_ARGUMENT, "paths");
-        }
     }
 
-    // TODO implement
     @RBuiltin(name = "Sys.chmod", visibility = OFF, kind = INTERNAL, parameterNames = {"paths", "octmode", "use_umask"}, behavior = IO)
     public abstract static class SysChmod extends RBuiltinNode {
+        @Override
+        protected void createCasts(CastBuilder casts) {
+            casts.arg("paths").mustBe(stringValue());
+            casts.arg("octmode").asIntegerVector().mustBe(notEmpty(), RError.Message.MODE_LENGTH_ONE);
+            casts.arg("use_umask").asLogicalVector().findFirst().notNA().map(toBoolean());
+        }
+
         @Specialization
         @TruffleBoundary
-        protected RLogicalVector sysChmod(RAbstractStringVector pathVec, RAbstractIntVector octmode, @SuppressWarnings("unused") byte useUmask) {
+        protected RLogicalVector sysChmod(RAbstractStringVector pathVec, RAbstractIntVector octmode, @SuppressWarnings("unused") boolean useUmask) {
             byte[] data = new byte[pathVec.getLength()];
             for (int i = 0; i < data.length; i++) {
                 String path = Utils.tildeExpand(pathVec.getDataAt(i));
@@ -318,10 +299,15 @@ public class SysFunctions {
     // TODO implement
     @RBuiltin(name = "Sys.umask", visibility = CUSTOM, kind = INTERNAL, parameterNames = {"octmode"}, behavior = COMPLEX)
     public abstract static class SysUmask extends RBuiltinNode {
+        @Override
+        protected void createCasts(CastBuilder casts) {
+            casts.arg("octmode").asIntegerVector().findFirst();
+        }
+
         @SuppressWarnings("unused")
         @Specialization
         @TruffleBoundary
-        protected Object sysChmod(Object octmode) {
+        protected Object sysUmask(int octmode) {
             throw RError.nyi(this, "Sys.umask");
         }
     }
@@ -361,10 +347,15 @@ public class SysFunctions {
 
     @RBuiltin(name = "Sys.glob", kind = INTERNAL, parameterNames = {"paths", "dirmask"}, behavior = IO)
     public abstract static class SysGlob extends RBuiltinNode {
+        @Override
+        protected void createCasts(CastBuilder casts) {
+            casts.arg("paths").mustBe(stringValue()).asStringVector();
+            casts.arg("dirmask").asLogicalVector().findFirst().notNA().map(toBoolean());
+        }
 
         @Specialization
         @TruffleBoundary
-        protected Object sysGlob(RAbstractStringVector pathVec, @SuppressWarnings("unused") byte dirMask) {
+        protected Object sysGlob(RAbstractStringVector pathVec, @SuppressWarnings("unused") boolean dirMask) {
             ArrayList<String> matches = new ArrayList<>();
             // Sys.glob closure already called path.expand
             for (int i = 0; i < pathVec.getLength(); i++) {
diff --git a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/Warning.java b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/Warning.java
index 6ee52996d3b615a84c3bc978430ab84f9962f23d..64b2b539db2bc7035e609b4a8ef40b3d31008094 100644
--- a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/Warning.java
+++ b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/Warning.java
@@ -22,58 +22,38 @@
  */
 package com.oracle.truffle.r.nodes.builtin.base;
 
+import static com.oracle.truffle.r.nodes.builtin.CastBuilder.Predef.*;
 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;
 
 import com.oracle.truffle.api.CompilerDirectives;
 import com.oracle.truffle.api.CompilerDirectives.TruffleBoundary;
-import com.oracle.truffle.api.dsl.Fallback;
 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.RError;
 import com.oracle.truffle.r.runtime.RErrorHandling;
-import com.oracle.truffle.r.runtime.RRuntime;
 import com.oracle.truffle.r.runtime.builtins.RBuiltin;
 
 @RBuiltin(name = "warning", visibility = OFF, kind = INTERNAL, parameterNames = {"call", "immediate", "nobreaks", "message"}, behavior = COMPLEX)
 public abstract class Warning extends RBuiltinNode {
 
-    @Child private CastStringNode castString;
-
-    private Object castString(Object operand) {
-        if (castString == null) {
-            CompilerDirectives.transferToInterpreterAndInvalidate();
-            castString = insert(CastStringNodeGen.create(false, false, false));
-        }
-        return castString.execute(operand);
-    }
-
     @Override
     protected void createCasts(CastBuilder casts) {
-        casts.toLogical(0);
-        casts.toLogical(1);
-        casts.toLogical(2);
+        casts.arg("call").asLogicalVector().findFirst().map(toBoolean());
+        casts.arg("immediate").asLogicalVector().findFirst().map(toBoolean());
+        casts.arg("nobreaks").asLogicalVector().findFirst().map(toBoolean());
+        casts.arg("message").mustBe(stringValue()).asStringVector().mustBe(notEmpty(), RError.Message.INVALID_STRING_IN_WARNING).findFirst();
+
     }
 
     @Specialization
     @TruffleBoundary
-    protected String warning(byte callL, byte immediateL, byte noBreakWarningL, Object messageObj) {
-        String message = RRuntime.asString(castString(messageObj));
-        boolean call = RRuntime.fromLogical(callL);
-        boolean immediate = RRuntime.fromLogical(immediateL);
-        boolean noBreakWarning = RRuntime.fromLogical(noBreakWarningL);
+    protected String warning(boolean call, boolean immediate, boolean noBreakWarning, String message) {
+        CompilerDirectives.transferToInterpreter();
         RErrorHandling.warningcallInternal(call, message, immediate, noBreakWarning);
         return message;
     }
 
-    @SuppressWarnings("unused")
-    @Fallback
-    @TruffleBoundary
-    protected String warning(Object callL, Object immediateL, Object noBreakWarningL, Object message) {
-        throw RError.error(this, RError.Message.INVALID_OR_UNIMPLEMENTED_ARGUMENTS);
-    }
 }
diff --git a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/WithVisible.java b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/WithVisible.java
index abc807d0118d0b82c3e92ef2f59850058aebbd3a..ac1c17063144512e320092bfa7a4193bdf381e4f 100644
--- a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/WithVisible.java
+++ b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/WithVisible.java
@@ -22,40 +22,43 @@
  */
 package com.oracle.truffle.r.nodes.builtin.base;
 
+import static com.oracle.truffle.r.nodes.builtin.CastBuilder.Predef.*;
 import static com.oracle.truffle.r.runtime.builtins.RBehavior.COMPLEX;
 import static com.oracle.truffle.r.runtime.builtins.RBuiltinKind.PRIMITIVE;
 
 import com.oracle.truffle.api.dsl.Specialization;
+import com.oracle.truffle.r.nodes.builtin.CastBuilder;
 import com.oracle.truffle.r.nodes.builtin.RBuiltinNode;
+import com.oracle.truffle.r.runtime.FastROptions;
 import com.oracle.truffle.r.runtime.RError;
-import com.oracle.truffle.r.runtime.RError.Message;
 import com.oracle.truffle.r.runtime.RRuntime;
 import com.oracle.truffle.r.runtime.builtins.RBuiltin;
 import com.oracle.truffle.r.runtime.context.RContext;
 import com.oracle.truffle.r.runtime.data.RDataFactory;
 import com.oracle.truffle.r.runtime.data.RList;
-import com.oracle.truffle.r.runtime.data.RMissing;
 import com.oracle.truffle.r.runtime.data.RStringVector;
 
+// TODO The base package manual says this is a primitive but GNU R implements it as .Internal.
+// That causes problems as the .Internal adds another layer of visibility setting that
+// gets the wrong result. I believe that the only way to handle it as a .Internal would be to
+// set noEvalArgs and evaluate the argument here and set the visibility explicitly.
 @RBuiltin(name = "withVisible", kind = PRIMITIVE, parameterNames = "x", behavior = COMPLEX)
 public abstract class WithVisible extends RBuiltinNode {
     private static final RStringVector LISTNAMES = RDataFactory.createStringVector(new String[]{"value", "visible"}, RDataFactory.COMPLETE_VECTOR);
 
-    @Specialization(guards = "!isRMissing(x)")
+    @Override
+    protected void createCasts(CastBuilder casts) {
+        casts.arg("x").mustBe(missingValue().not(), RError.Message.ARGUMENT_MISSING, "x");
+    }
+
+    @Specialization
     protected RList withVisible(Object x) {
-        // (LS) temporarily disabled to enable parallel benchmarks
-        // if (FastROptions.IgnoreVisibility.getBooleanValue()) {
-        // RError.warning(this, RError.Message.GENERIC, "using withVisible with IgnoreVisibility");
-        // }
+        if (FastROptions.IgnoreVisibility.getBooleanValue()) {
+            RError.warning(this, RError.Message.GENERIC, "using withVisible with IgnoreVisibility");
+        }
 
         Object[] data = new Object[]{x, RRuntime.asLogical(RContext.getInstance().isVisible())};
-        // Visibility is changed by the evaluation (else this code would not work),
-        // so we have to force it back on.
         return RDataFactory.createList(data, LISTNAMES);
     }
 
-    @Specialization
-    protected RList withVisible(@SuppressWarnings("unused") RMissing x) {
-        throw RError.error(this, Message.ARGUMENT_MISSING, "x");
-    }
 }
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 108a51926b12a0273dd3aa891d1fcc2038f2f464..3015d06283eee674f9385c5c8f16c02bcc1892bb 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
@@ -262,7 +262,6 @@ public final class RError extends RuntimeException {
         MUST_BE_SQUARE_COMPATIBLE("'%s' (%d x %d) must be compatible with '%' (%d x %d)"),
         INVALID_TFB("invalid (to - from)/by in seq(.)"),
         WRONG_SIGN_IN_BY("wrong sign in 'by' argument"),
-        WRONG_TYPE("wrong type of argument"),
         BY_TOO_SMALL("'by' argument is much too small"),
         INCORRECT_SUBSCRIPTS("incorrect number of subscripts"),
         INCORRECT_SUBSCRIPTS_MATRIX("incorrect number of subscripts on matrix"),
@@ -301,6 +300,7 @@ public final class RError extends RuntimeException {
         ARGUMENT_LENGTHS_DIFFER("argument lengths differ"),
         ZERO_LENGTH_PATTERN("zero-length pattern"),
         UNSUPPORTED_MODE("unsupported mode"),
+        MODE_LENGTH_ONE("'mode' must be of length at least one"),
         ALL_CONNECTIONS_IN_USE("all connections are in use"),
         CANNOT_READ_CONNECTION("cannot read from this connection"),
         CONNECTION_NOT_OPEN_READ("connection not open for reading"),
@@ -326,6 +326,8 @@ public final class RError extends RuntimeException {
         NAMES_NONVECTOR("names() applied to a non-vector"),
         NAMES_LONGER("'names' attribute [%d] must be the same length as the vector [%d]"),
         ONLY_FIRST_VARIABLE_NAME("only the first element is used as variable name"),
+        INVALID_FIRST_FILENAME("invalid first filename"),
+        INVALID_SECOND_FILENAME("invalid second filename"),
         INVALID_FIRST_ARGUMENT("invalid first argument"),
         NO_ENCLOSING_ENVIRONMENT("no enclosing environment"),
         ASSIGN_EMPTY("cannot assign values in the empty environment"),
@@ -337,6 +339,9 @@ public final class RError extends RuntimeException {
         COERCING_LHS_TO_LIST("Coercing LHS to a list"),
         ARGUMENT_NOT_LIST("argument not a list"),
         FIRST_ARGUMENT_NOT_NAMED_LIST("first argument must be a named list"),
+        FIRST_ARGUMENT_NOT_CHARVEC("first argument must be a character vector"),
+        FIRST_ARGUMENT_NOT_FILENAME("first argument must be a filename"),
+        ASCII_NOT_LOGICAL("'ascii' must be logical"),
         LIST_NAMES_SAME_LENGTH("names(x) must be a character vector of the same length as x"),
         DIMS_CONTAIN_NEGATIVE_VALUES("the dims contain negative values"),
         NEGATIVE_LENGTH_VECTORS_NOT_ALLOWED("negative length vectors are not allowed"),
@@ -415,6 +420,8 @@ public final class RError extends RuntimeException {
         CANNOT_COERCE("cannot coerce type '%s' to vector of type '%s'"),
         ARGUMENT_ONLY_FIRST("argument '%s' has length > 1 and only the first element will be used"),
         ARGUMENT_ONLY_FIRST_1("only the first element of '%s' argument used"),
+        ARGUMENT_WRONG_LENGTH("wrong length for argument"),
+        ARGUMENT_WRONG_TYPE("wrong type for argument"),
         CANNOT_OPEN_FILE("cannot open file '%s': %s"),
         NOT_CONNECTION("'%s' is not a connection"),
         UNUSED_TEXTCONN("closing unused text connection %d (%s)"),
@@ -692,6 +699,11 @@ public final class RError extends RuntimeException {
         SYSTEM_CHAR_ARG("non-empty character argument expected"),
         SYSTEM_INTERN_NOT_NA("'intern' must be logical and not NA"),
         NO_SUCH_FILE("cannot open file '%s': No such file or directory"),
+        NON_STRING_ARG_TO_INTERNAL_PASTE("non-string argument to Internal paste"),
+        INVALID_STRING_IN_STOP(" [invalid string in stop(.)]"),
+        INVALID_STRING_IN_WARNING(" [invalid string in warning(.)]"),
+        ERR_MSG_MUST_BE_STRING("error message must be a character string"),
+        ERR_MSG_BAD("bad error message"),
         CANNOT_BE_LENGTH("'%s' cannot be of length %d");
 
         public final String message;