diff --git a/com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/methods/MethodsListDispatch.java b/com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/methods/MethodsListDispatch.java
index 113e978f5282df6795529eb754e586ba158f2a65..3e8b28ed974eef02fe102aaf02086d6554704dc9 100644
--- a/com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/methods/MethodsListDispatch.java
+++ b/com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/methods/MethodsListDispatch.java
@@ -13,6 +13,7 @@ package com.oracle.truffle.r.library.methods;
 
 import static com.oracle.truffle.r.nodes.builtin.CastBuilder.Predef.instanceOf;
 import static com.oracle.truffle.r.nodes.builtin.CastBuilder.Predef.lengthGt;
+import static com.oracle.truffle.r.nodes.builtin.CastBuilder.Predef.lengthGte;
 import static com.oracle.truffle.r.nodes.builtin.CastBuilder.Predef.singleElement;
 import static com.oracle.truffle.r.nodes.builtin.CastBuilder.Predef.stringValue;
 import static com.oracle.truffle.r.nodes.builtin.CastBuilder.Predef.toBoolean;
@@ -55,7 +56,6 @@ import com.oracle.truffle.r.runtime.data.RLanguage;
 import com.oracle.truffle.r.runtime.data.RNull;
 import com.oracle.truffle.r.runtime.data.RPromise;
 import com.oracle.truffle.r.runtime.data.RS4Object;
-import com.oracle.truffle.r.runtime.data.RStringVector;
 import com.oracle.truffle.r.runtime.data.RTypedValue;
 import com.oracle.truffle.r.runtime.data.model.RAbstractStringVector;
 import com.oracle.truffle.r.runtime.env.REnvironment;
@@ -68,6 +68,18 @@ import com.oracle.truffle.r.runtime.nodes.RSyntaxNode;
 
 public class MethodsListDispatch {
 
+    private static void checkSingleString(CastBuilder casts, int argNum, String argName, String msg, boolean nonEmpty, Function<Object, String> clsHierFn, Function<Object, Integer> vecLenFn) {
+        //@formatter:off
+        casts.arg(argNum, argName).
+            defaultError(RError.NO_CALLER, RError.Message.SINGLE_STRING_WRONG_TYPE, msg, clsHierFn).
+            mustBe(stringValue()).
+            asStringVector().
+            mustBe(singleElement(), RError.NO_CALLER, RError.Message.SINGLE_STRING_TOO_LONG, msg, vecLenFn).
+            findFirst().
+            mustBe(nonEmpty ? lengthGt(0) : lengthGte(0), RError.NO_CALLER, RError.Message.NON_EMPTY_STRING, msg);
+        //@formatter:on
+    }
+
     public abstract static class R_initMethodDispatch extends RExternalBuiltinNode.Arg1 {
 
         @Specialization
@@ -87,19 +99,23 @@ public class MethodsListDispatch {
 
     public abstract static class R_methodsPackageMetaName extends RExternalBuiltinNode.Arg3 {
 
+        @Override
+        protected void createCasts(CastBuilder casts) {
+            Function<Object, String> clsHierFn = ClassHierarchyScalarNode::get;
+            Function<Object, Integer> vecLenFn = arg -> ((RAbstractStringVector) arg).getLength();
+
+            checkSingleString(casts, 0, "prefix", "The internal prefix (e.g., \"C\") for a meta-data object", true, clsHierFn, vecLenFn);
+            checkSingleString(casts, 1, "name", "The name of the object (e.g,. a class or generic function) to find in the meta-data", false, clsHierFn, vecLenFn);
+            checkSingleString(casts, 2, "pkg", "The name of the package for a meta-data object", false, clsHierFn, vecLenFn);
+        }
+
         @Specialization
         @TruffleBoundary
-        protected String callMethodsPackageMetaName(RAbstractStringVector prefixStringVector, RAbstractStringVector nameStringVector, RAbstractStringVector pkgStringVector) {
-            // TODO: proper error messages
-            assert prefixStringVector.getLength() == 1 && nameStringVector.getLength() == 1 && pkgStringVector.getLength() == 1;
-            String prefixString = prefixStringVector.getDataAt(0);
-            String nameString = nameStringVector.getDataAt(0);
-            String pkgString = pkgStringVector.getDataAt(0);
-
-            if (pkgString.length() == 0) {
-                return ".__" + prefixString + "__" + nameString;
+        protected String callMethodsPackageMetaName(String prefix, String name, String pkg) {
+            if (pkg.length() == 0) {
+                return ".__" + prefix + "__" + name;
             } else {
-                return ".__" + prefixString + "__" + nameString + ":" + pkgString;
+                return ".__" + prefix + "__" + name + ":" + pkg;
             }
         }
     }
@@ -300,14 +316,7 @@ public class MethodsListDispatch {
             //@formatter:off
             Function<Object, Integer> vecLenFn = arg -> ((RAbstractStringVector) arg).getLength();
 
-            String msg0 = "The argument \"f\" to getGeneric";
-            casts.arg(0, "f").
-                defaultError(RError.NO_CALLER, RError.Message.SINGLE_STRING_WRONG_TYPE, msg0, clsHierFn).
-                mustBe(stringValue()).
-                asStringVector().
-                mustBe(singleElement(), RError.NO_CALLER, RError.Message.SINGLE_STRING_TOO_LONG, msg0, vecLenFn).
-                findFirst().
-                mustBe(lengthGt(0), RError.NO_CALLER, RError.Message.NON_EMPTY_STRING, msg0);
+            checkSingleString(casts, 0, "f", "The argument \"f\" to getGeneric", true, clsHierFn, vecLenFn);
 
             casts.arg(1, "mustFind").
                 asLogicalVector().
@@ -317,13 +326,7 @@ public class MethodsListDispatch {
             casts.arg(2, "env").
                 mustBe(instanceOf(REnvironment.class));
 
-            String msg1 = "The argument \"package\" to getGeneric";
-            casts.arg(3, "package").
-                defaultError(RError.NO_CALLER, RError.Message.SINGLE_STRING_WRONG_TYPE, msg1, clsHierFn).
-                mustBe(stringValue()).
-                asStringVector().
-                mustBe(singleElement(), RError.NO_CALLER, RError.Message.SINGLE_STRING_TOO_LONG, msg1, vecLenFn).
-                findFirst();
+            checkSingleString(casts, 3, "package", "The argument \"package\" to getGeneric", false, clsHierFn, vecLenFn);
             //@formatter:on
         }
 
diff --git a/com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/tools/C_ParseRd.java b/com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/tools/C_ParseRd.java
index 4eab6dfc718fa092d6d56eec4234770ad1e5b21e..a67b35e7adb2026afbfdb1121c058b2408b4b523 100644
--- a/com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/tools/C_ParseRd.java
+++ b/com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/tools/C_ParseRd.java
@@ -22,18 +22,23 @@
  */
 package com.oracle.truffle.r.library.tools;
 
-import java.io.IOException;
+import static com.oracle.truffle.r.nodes.builtin.CastBuilder.Predef.instanceOf;
+import static com.oracle.truffle.r.nodes.builtin.CastBuilder.Predef.logicalValue;
+import static com.oracle.truffle.r.nodes.builtin.CastBuilder.Predef.stringValue;
 
 import com.oracle.truffle.api.CompilerDirectives.TruffleBoundary;
+import com.oracle.truffle.api.dsl.Cached;
 import com.oracle.truffle.api.dsl.Fallback;
 import com.oracle.truffle.api.dsl.Specialization;
 import com.oracle.truffle.r.nodes.builtin.CastBuilder;
 import com.oracle.truffle.r.nodes.builtin.RExternalBuiltinNode;
+import com.oracle.truffle.r.nodes.ffi.AsIntegerNode;
+import com.oracle.truffle.r.nodes.ffi.AsLogicalNode;
 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.conn.RConnection;
 import com.oracle.truffle.r.runtime.data.RDataFactory;
+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.ffi.RFFIFactory;
@@ -44,38 +49,43 @@ public abstract class C_ParseRd extends RExternalBuiltinNode.Arg9 {
 
     @Override
     protected void createCasts(CastBuilder casts) {
-        casts.arg(0).defaultError(Message.INVALID_CONNECTION).mustNotBeNull().asIntegerVector().findFirst();
-    }
-
-    @Specialization
-    protected Object parseRd(int con, REnvironment srcfile, String encoding, byte verboseL, RAbstractStringVector basename, byte fragmentL, byte warningCallsL, byte macrosL, byte warndupsL) {
-        return doParseRd(con, srcfile, encoding, verboseL, basename, fragmentL, warningCallsL, RDataFactory.createLogicalVectorFromScalar(macrosL), warndupsL);
-    }
-
-    @Specialization
-    protected Object parseRd(int con, REnvironment srcfile, String encoding, byte verboseL, RAbstractStringVector basename, byte fragmentL, byte warningCallsL, REnvironment macros, byte warndupsL) {
-        return doParseRd(con, srcfile, encoding, verboseL, basename, fragmentL, warningCallsL, macros, warndupsL);
+        /*
+         * Most arguments require coercion using, e.g., asLogical; N.B. GNU R doesn't check
+         * everything, e.g., srcfile. Since this is "internal" code we do not really expect argument
+         * errors.
+         */
+        casts.arg(1, "srcfile").mustBe(instanceOf(REnvironment.class));
+        casts.arg(3, "verbose").mustBe(logicalValue()).asLogicalVector();
+        casts.arg(4, "basename").mustBe(stringValue()).asStringVector();
     }
 
     @TruffleBoundary
-    private Object doParseRd(int con, REnvironment srcfile, @SuppressWarnings("unused") String encoding, byte verboseL, RAbstractStringVector basename, byte fragmentL, byte warningCallsL,
-                    Object macros, byte warndupsL) {
-        if (RRuntime.isNA(warningCallsL)) {
-            throw RError.error(this, RError.Message.INVALID_ARGUMENT, "warningCalls");
+    @Specialization
+    protected Object parseRd(Object conObj, REnvironment srcfile, @SuppressWarnings("unused") Object encoding, RAbstractLogicalVector verbose, RAbstractStringVector basename, Object fragmentObj,
+                    Object warningCallsObj, Object macros, Object warndupsObj,
+                    @Cached("create()") AsIntegerNode conAsInteger,
+                    @Cached("create()") AsLogicalNode fragmentAsLogical,
+                    @Cached("create()") AsLogicalNode warningCallsAsLogical,
+                    @Cached("create()") AsLogicalNode warnDupsAsLogical) {
+        int con = conAsInteger.execute(conObj);
+        int warningCalls = warningCallsAsLogical.execute(warningCallsObj);
+        if (RRuntime.isNA(warningCalls)) {
+            throw RError.error(this, RError.Message.INVALID_VALUE, "warningCalls");
         }
+        int fragment = fragmentAsLogical.execute(fragmentObj);
+        int warndups = warnDupsAsLogical.execute(warndupsObj);
 
+        // fromIndex checks validity of con and throws error if not
         try (RConnection openConn = RConnection.fromIndex(con).forceOpen("r")) {
             // @formatter:off
             return toolsRFFINode.parseRd(openConn, srcfile,
-                            RDataFactory.createLogicalVectorFromScalar(verboseL),
-                            RDataFactory.createLogicalVectorFromScalar(fragmentL),
-                            RDataFactory.createStringVectorFromScalar(basename.getDataAt(0)),
-                            RDataFactory.createLogicalVectorFromScalar(warningCallsL),
+                            verbose.materialize(),
+                            RDataFactory.createLogicalVectorFromScalar((byte) fragment),
+                            basename.materialize(),
+                            RDataFactory.createLogicalVectorFromScalar((byte) warningCalls),
                             macros,
-                            RDataFactory.createLogicalVectorFromScalar(warndupsL));
+                            RDataFactory.createLogicalVectorFromScalar((byte) warndups));
             // @formatter:on
-        } catch (IOException ex) {
-            throw RError.error(this, RError.Message.GENERIC, ex.getMessage());
         } catch (Throwable ex) {
             throw RError.error(this, RError.Message.GENERIC, ex.getMessage());
         }
diff --git a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/function/S3FunctionLookupNode.java b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/function/S3FunctionLookupNode.java
index 27352dc09f5c1f2a2a62d58fcb06cf47e929e416..bbce4bf49e0fc2c3d86a9cc6fc882f2d635a9e4e 100644
--- a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/function/S3FunctionLookupNode.java
+++ b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/function/S3FunctionLookupNode.java
@@ -33,6 +33,7 @@ import com.oracle.truffle.r.nodes.access.variables.LocalReadVariableNode;
 import com.oracle.truffle.r.nodes.access.variables.ReadVariableNode;
 import com.oracle.truffle.r.runtime.ArgumentsSignature;
 import com.oracle.truffle.r.runtime.RArguments.S3Args;
+import com.oracle.truffle.r.runtime.RDispatch;
 import com.oracle.truffle.r.runtime.RError;
 import com.oracle.truffle.r.runtime.RInternalError;
 import com.oracle.truffle.r.runtime.RRuntime;
diff --git a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/function/call/RExplicitCallNode.java b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/function/call/RExplicitCallNode.java
index 3868c0d29e32c66fe4bde0466ef4e360db3c9fab..c2c0162bfa59e6808708b553ebe5f158927d7ea8 100644
--- a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/function/call/RExplicitCallNode.java
+++ b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/function/call/RExplicitCallNode.java
@@ -54,7 +54,7 @@ public abstract class RExplicitCallNode extends Node {
 
     @Specialization
     Object doCall(VirtualFrame frame, RFunction function, RArgsValuesAndNames args,
-                    @Cached("createArgsIdentifier()") Object argsIdentifier,
+                    @SuppressWarnings("unused") @Cached("createArgsIdentifier()") Object argsIdentifier,
                     @Cached("createExplicitCall(argsIdentifier)") RCallBaseNode call,
                     @Cached("createFrameSlotNode(argsIdentifier)") FrameSlotNode argumentsSlot) {
         FrameSlot argsFrameSlot = argumentsSlot.executeFrameSlot(frame);