diff --git a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/builtin/casts/fluent/PreinitialPhaseBuilder.java b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/builtin/casts/fluent/PreinitialPhaseBuilder.java
index b54e004571f27eb45d2fb3102d9ea09169466e58..8a29918d6408dd60d46a1ff2fa1aa3646a0eef38 100644
--- a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/builtin/casts/fluent/PreinitialPhaseBuilder.java
+++ b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/builtin/casts/fluent/PreinitialPhaseBuilder.java
@@ -99,9 +99,6 @@ public final class PreinitialPhaseBuilder extends InitialPhaseBuilder<Object> {
     /**
      * Determines whether foreign arrays are implicitly casted to a R vector/list or not. <br>
      * The default setting is <code>true</code>.
-     * 
-     * @param flag
-     * @return
      */
     public PreinitialPhaseBuilder castForeignObjects(boolean flag) {
         pipelineBuilder().getPipelineConfig().setCastForeignObjects(flag);
diff --git a/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/interop/Foreign2R.java b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/interop/Foreign2R.java
index 23b3b20dfb84afe5e585c692b7a11146e06f75ad..5642fa86b7857bc1780b2f765ce375f571841be6 100644
--- a/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/interop/Foreign2R.java
+++ b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/interop/Foreign2R.java
@@ -22,17 +22,27 @@
  */
 package com.oracle.truffle.r.runtime.interop;
 
+import com.oracle.truffle.api.CompilerDirectives;
 import com.oracle.truffle.api.dsl.Fallback;
 import com.oracle.truffle.api.dsl.ImportStatic;
 import com.oracle.truffle.api.dsl.Specialization;
+import com.oracle.truffle.api.interop.ForeignAccess;
 import com.oracle.truffle.api.interop.Message;
+import com.oracle.truffle.api.interop.TruffleObject;
+import com.oracle.truffle.api.interop.UnsupportedMessageException;
+import com.oracle.truffle.api.nodes.Node;
+import com.oracle.truffle.r.runtime.RInternalError;
 import com.oracle.truffle.r.runtime.RRuntime;
 import com.oracle.truffle.r.runtime.data.RNull;
 import com.oracle.truffle.r.runtime.nodes.RBaseNode;
 
-@ImportStatic(Message.class)
+@ImportStatic({RRuntime.class})
 public abstract class Foreign2R extends RBaseNode {
 
+    @Child private Foreign2R recursive;
+    @Child private Node isBoxed;
+    @Child private Node unbox;
+
     public static Foreign2R createForeign2R() {
         return Foreign2RNodeGen.create();
     }
@@ -74,6 +84,37 @@ public abstract class Foreign2R extends RBaseNode {
         return RNull.instance;
     }
 
+    @Specialization(guards = "isForeignObject(obj)")
+    public Object doUnbox(TruffleObject obj) {
+        /*
+         * For the time being, we have to ask "IS_BOXED" all the time (instead of simply trying
+         * UNBOX first), because some TruffleObjects return bogus values from UNBOX when IS_BOXED is
+         * false.
+         */
+        if (isBoxed == null) {
+            CompilerDirectives.transferToInterpreterAndInvalidate();
+            isBoxed = insert(Message.IS_BOXED.createNode());
+        }
+        if (ForeignAccess.sendIsBoxed(isBoxed, obj)) {
+            if (unbox == null) {
+                CompilerDirectives.transferToInterpreterAndInvalidate();
+                unbox = insert(Message.UNBOX.createNode());
+            }
+            try {
+                Object unboxed = ForeignAccess.sendUnbox(unbox, obj);
+                if (recursive == null) {
+                    CompilerDirectives.transferToInterpreterAndInvalidate();
+                    recursive = insert(Foreign2RNodeGen.create());
+                }
+                return recursive.execute(unboxed);
+            } catch (UnsupportedMessageException e) {
+                CompilerDirectives.transferToInterpreter();
+                throw RInternalError.shouldNotReachHere(e, "object does not support UNBOX message even though IS_BOXED == true: " + obj.getClass().getSimpleName());
+            }
+        }
+        return obj;
+    }
+
     @Fallback
     public Object doObject(Object obj) {
         return obj;
diff --git a/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/interop/ForeignArray2R.java b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/interop/ForeignArray2R.java
index 9a75f0c138bc3483162f99115b8bca3264901fc6..ebf2d491225124af8bb65854e424c342c044ae02 100644
--- a/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/interop/ForeignArray2R.java
+++ b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/interop/ForeignArray2R.java
@@ -192,9 +192,6 @@ public abstract class ForeignArray2R extends RBaseNode {
 
     /**
      * Converts the elements collected from a foreign array or java iterable into a vector or list.
-     * 
-     * @param ce
-     * @return
      */
     public static RAbstractVector asAbstractVector(CollectedElements ce) {
         InteropTypeCheck.RType type = ce.typeCheck.getType();