diff --git a/com.oracle.truffle.r.native/fficall/src/jni/Rinternals.c b/com.oracle.truffle.r.native/fficall/src/jni/Rinternals.c
index c8ef247f6f7abc76ac41990dbf06f05d035dcc58..d097f37157957d136746c9e209fd3834bd0c0f8d 100644
--- a/com.oracle.truffle.r.native/fficall/src/jni/Rinternals.c
+++ b/com.oracle.truffle.r.native/fficall/src/jni/Rinternals.c
@@ -715,7 +715,7 @@ const char *Rf_translateCharUTF8(SEXP x) {
 SEXP Rf_lengthgets(SEXP x, R_len_t y) {
 	TRACE(TARGp, x);
 	JNIEnv *thisenv = getEnv();
-	invalidateCopiedObject(thisenv, x);
+	invalidateNativeArray(thisenv, x);
 	SEXP result = (*thisenv)->CallStaticObjectMethod(thisenv, CallRFFIHelperClass, Rf_lengthgetsMethodID, x, y);
 	return checkRef(thisenv, result);
 }
diff --git a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/foreign/DotC.java b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/foreign/DotC.java
index 60f28c4e3c08f2e47e3f6efaf291fc0a47e8526f..5b859523cf466216bc992d97418613df6164e8d2 100644
--- a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/foreign/DotC.java
+++ b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/foreign/DotC.java
@@ -206,7 +206,14 @@ public abstract class DotC extends RBuiltinNode {
                     results[i] = RDataFactory.createIntVector((int[]) nativeArgs[i], RDataFactory.COMPLETE_VECTOR);
                     break;
                 case SCALAR_LOGICAL:
-                    results[i] = RDataFactory.createLogicalVector((byte[]) nativeArgs[i], RDataFactory.COMPLETE_VECTOR);
+                    // have to convert back from int[]
+                    int[] nativeIntArgs = (int[]) nativeArgs[i];
+                    byte[] nativeByteArgs = new byte[nativeIntArgs.length];
+                    for (int j = 0; j < nativeByteArgs.length; j++) {
+                        int nativeInt = nativeIntArgs[j];
+                        nativeByteArgs[j] = (byte) (nativeInt == RRuntime.INT_NA ? RRuntime.LOGICAL_NA : nativeInt & 0xFF);
+                    }
+                    results[i] = RDataFactory.createLogicalVector(nativeByteArgs, RDataFactory.COMPLETE_VECTOR);
                     break;
                 case VECTOR_DOUBLE:
                     results[i] = ((RAbstractDoubleVector) array[i]).materialize().copyResetData((double[]) nativeArgs[i]);
diff --git a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/foreign/ForeignFunctions.java b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/foreign/ForeignFunctions.java
index bd01a896e59b7d4c30544cdec78bebafca66c4bc..14adfe090df8ff15546d3b3680d86abfba13f872 100644
--- a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/foreign/ForeignFunctions.java
+++ b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/foreign/ForeignFunctions.java
@@ -45,6 +45,7 @@ import com.oracle.truffle.r.library.parallel.ParallelFunctionsFactory.MCIsChildN
 import com.oracle.truffle.r.library.stats.CdistNodeGen;
 import com.oracle.truffle.r.library.stats.CompleteCases;
 import com.oracle.truffle.r.library.stats.CovcorNodeGen;
+import com.oracle.truffle.r.library.stats.CutreeNodeGen;
 import com.oracle.truffle.r.library.stats.Dbinom;
 import com.oracle.truffle.r.library.stats.DoubleCentreNodeGen;
 import com.oracle.truffle.r.library.stats.GammaFunctionsFactory.QgammaNodeGen;
@@ -383,8 +384,8 @@ public class ForeignFunctions {
                     return CdistNodeGen.create();
                 case "DoubleCentre":
                     return DoubleCentreNodeGen.create();
-
                 case "cutree":
+                    return CutreeNodeGen.create();
                 case "isoreg":
                 case "monoFC_m":
                 case "numeric_deriv":
diff --git a/com.oracle.truffle.r.runtime.ffi/src/com/oracle/truffle/r/runtime/ffi/jni/CallRFFIHelper.java b/com.oracle.truffle.r.runtime.ffi/src/com/oracle/truffle/r/runtime/ffi/jni/CallRFFIHelper.java
index f1818466bd3b1643929479caff96594ccd93fb1c..add58098c44adde2a5b5cd6009911202cb70cba0 100644
--- a/com.oracle.truffle.r.runtime.ffi/src/com/oracle/truffle/r/runtime/ffi/jni/CallRFFIHelper.java
+++ b/com.oracle.truffle.r.runtime.ffi/src/com/oracle/truffle/r/runtime/ffi/jni/CallRFFIHelper.java
@@ -79,6 +79,7 @@ import com.oracle.truffle.r.runtime.env.REnvironment.PutException;
 import com.oracle.truffle.r.runtime.ffi.RFFIUtils;
 import com.oracle.truffle.r.runtime.gnur.SEXPTYPE;
 import com.oracle.truffle.r.runtime.nodes.DuplicationHelper;
+import com.oracle.truffle.r.runtime.nodes.RNode;
 import com.oracle.truffle.r.runtime.rng.RRNG;
 
 /**
@@ -86,6 +87,13 @@ import com.oracle.truffle.r.runtime.rng.RRNG;
  * R header files, e.g. {@code Rinternals.h} that are used by C/C++ code. For ease of
  * identification, we use method names that, as far as possible, match the names in the header
  * files. These methods should never be called from normal FastR code.
+ *
+ * TODO Many of the implementations here are incomplete and/or duplicate code that exists in the
+ * Truffle side of the implementation, i.e., {@link RNode} subclasses. A complete refactoring that
+ * accesses the Truffle implementations (possibly somewhat refactored owing to the fact that the
+ * Truffle side is driven by the builtins yet these functions don't not always map 1-1 to a builtin)
+ * is desirable. In some cases it may be possible to "implement" the functions in R (which is a
+ * simple way to achieve the above).
  */
 public class CallRFFIHelper {
 
@@ -183,12 +191,15 @@ public class CallRFFIHelper {
         if (RFFIUtils.traceEnabled()) {
             RFFIUtils.traceUpCall("Rf_asInteger", x);
         }
+        // TODO this is quite incomplete and really should be implemented with CastIntegerNode
         if (x instanceof Integer) {
             return ((Integer) x).intValue();
         } else if (x instanceof Double) {
             return RRuntime.double2int((Double) x);
         } else if (x instanceof Byte) {
             return RRuntime.logical2int((Byte) x);
+        } else if (x instanceof RLogicalVector) {
+            return RRuntime.logical2int(((RLogicalVector) x).getDataAt(0));
         } else {
             guaranteeInstanceOf(x, RIntVector.class);
             return ((RIntVector) x).getDataAt(0);
@@ -722,7 +733,8 @@ public class CallRFFIHelper {
             RFFIUtils.traceUpCall("Rf_duplicate", x, deep);
         }
         guarantee(x != null, "unexpected type: null instead of " + x.getClass().getSimpleName());
-        guarantee(x instanceof RShareable || x instanceof RExternalPtr, "unexpected type: " + x + " is " + x.getClass().getSimpleName() + " instead of RShareable or RExternalPtr");
+        guarantee(x instanceof RShareable || x instanceof RIntSequence || x instanceof RExternalPtr,
+                        "unexpected type: " + x + " is " + x.getClass().getSimpleName() + " instead of RShareable or RExternalPtr");
         if (x instanceof RShareable) {
             return deep == 1 ? ((RShareable) x).deepCopy() : ((RShareable) x).copy();
         } else if (x instanceof RIntSequence) {