diff --git a/com.oracle.truffle.r.engine/src/com/oracle/truffle/r/engine/REngine.java b/com.oracle.truffle.r.engine/src/com/oracle/truffle/r/engine/REngine.java
index 61dc78f376e22a9f5c51367c0161864cd67eedb8..ec84baa9ed60d1161117164700bfa7e8d2c38e46 100644
--- a/com.oracle.truffle.r.engine/src/com/oracle/truffle/r/engine/REngine.java
+++ b/com.oracle.truffle.r.engine/src/com/oracle/truffle/r/engine/REngine.java
@@ -86,6 +86,7 @@ public final class REngine implements RContext.Engine {
         Locale.setDefault(Locale.ROOT);
         FastROptions.initialize();
         Load_RFFIFactory.initialize();
+        RAccuracyInfo.initialize();
         singleton.crashOnFatalError = crashOnFatalErrorArg;
         singleton.builtinLookup = RBuiltinPackages.getInstance();
         singleton.context = RContext.setRuntimeState(singleton, commandArgs, consoleHandler, new RASTHelperImpl(), headless);
@@ -95,7 +96,6 @@ public final class REngine implements RContext.Engine {
         singleton.evalFunction = singleton.lookupBuiltin("eval");
         RPackageVariables.initializeBase();
         RVersionInfo.initialize();
-        RAccuracyInfo.initialize();
         RRNG.initialize();
         TempDirPath.initialize();
         LibPaths.initialize();
diff --git a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/Abs.java b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/Abs.java
index 875fc3e7b5c42e8c25c97c9d5ea0723c734e0378..b0aa685d8fcc4459e28aed0e32ae036b2448a73b 100644
--- a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/Abs.java
+++ b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/Abs.java
@@ -41,7 +41,7 @@ public abstract class Abs extends RBuiltinNode {
     @Specialization
     protected RNull abs(RNull x) {
         controlVisibility();
-        throw RError.error(this.getEncapsulatingSourceSection(), RError.Message.NON_NUMERIC_ARGUMENT_FUNCTION);
+        throw RError.error(getEncapsulatingSourceSection(), RError.Message.NON_NUMERIC_ARGUMENT_FUNCTION);
     }
 
     @Specialization
@@ -79,14 +79,14 @@ public abstract class Abs extends RBuiltinNode {
     @Specialization
     protected Object abs(RRaw vector) {
         controlVisibility();
-        throw RError.error(this.getEncapsulatingSourceSection(), RError.Message.NON_NUMERIC_MATH);
+        throw RError.error(getEncapsulatingSourceSection(), RError.Message.NON_NUMERIC_MATH);
     }
 
     @SuppressWarnings("unused")
     @Specialization
     protected Object abs(String vector) {
         controlVisibility();
-        throw RError.error(this.getEncapsulatingSourceSection(), RError.Message.NON_NUMERIC_MATH);
+        throw RError.error(getEncapsulatingSourceSection(), RError.Message.NON_NUMERIC_MATH);
     }
 
     @Specialization
@@ -143,14 +143,14 @@ public abstract class Abs extends RBuiltinNode {
     @Specialization
     protected Object abs(RStringVector vector) {
         controlVisibility();
-        throw RError.error(this.getEncapsulatingSourceSection(), RError.Message.NON_NUMERIC_MATH);
+        throw RError.error(getEncapsulatingSourceSection(), RError.Message.NON_NUMERIC_MATH);
     }
 
     @SuppressWarnings("unused")
     @Specialization
     protected Object abs(RRawVector vector) {
         controlVisibility();
-        throw RError.error(this.getEncapsulatingSourceSection(), RError.Message.NON_NUMERIC_MATH);
+        throw RError.error(getEncapsulatingSourceSection(), RError.Message.NON_NUMERIC_MATH);
     }
 
     private int performInt(int value) {
diff --git a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/AsVector.java b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/AsVector.java
index 2711a58673ceff2f0271114a98d7144e3db8f0f7..4f4f891f4fd685a2b110d829d5b910f419ccc618 100644
--- a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/AsVector.java
+++ b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/AsVector.java
@@ -90,7 +90,7 @@ public abstract class AsVector extends RBuiltinNode {
     private RSymbol castSymbol(VirtualFrame frame, Object operand) {
         if (castSymbol == null) {
             CompilerDirectives.transferToInterpreterAndInvalidate();
-            castSymbol = insert(CastSymbolNodeFactory.create(null, false, false, false, false));
+            castSymbol = insert(CastSymbolNodeFactory.create(null, false, false, false));
         }
         return (RSymbol) castSymbol.executeSymbol(frame, operand);
     }
diff --git a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/BaseVariables.java b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/BaseVariables.java
index ae0cc149cbbc32f8b421ce5ba20aca3628303210..7fac75c41f6a7d35b16ebab1c68321b25d84b857 100644
--- a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/BaseVariables.java
+++ b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/BaseVariables.java
@@ -40,7 +40,7 @@ import com.oracle.truffle.r.runtime.env.REnvironment.*;
 public class BaseVariables implements RPackageVariables.Handler {
     // @formatter:off
     private static final String[] VARS = new String[]{
-        ".AutoloadEnv", ".BaseNamespaceEnv", ".GlobalEnv", ".Platform", ".Library", ".LibrarySite"
+        ".AutoloadEnv", ".BaseNamespaceEnv", ".GlobalEnv", ".Machine", ".Platform", ".Library", ".LibrarySite"
     };
     // @formatter:on
 
@@ -50,6 +50,7 @@ public class BaseVariables implements RPackageVariables.Handler {
     };
     // @formatter:on
 
+    // @formatter:off
     private int initialized = -1;
 
     public BaseVariables() {
@@ -77,6 +78,9 @@ public class BaseVariables implements RPackageVariables.Handler {
                         String[] platformData = new String[]{"unix", File.separator, ".so", "unknown", "little", "source", File.pathSeparator, ""};
                         value = RDataFactory.createList(platformData, RDataFactory.createStringVector(PLATFORM_NAMES, RDataFactory.COMPLETE_VECTOR));
                         break;
+                    case ".Machine":
+                        value = createMachine();
+                        break;
                     default:
                         continue;
                 }
@@ -110,4 +114,39 @@ public class BaseVariables implements RPackageVariables.Handler {
         initialized++;
     }
 
+    private static final String[] MACHINE_NAMES = new String[] {
+        "double.eps",            "double.neg.eps",        "double.xmin",
+        "double.xmax",           "double.base",           "double.digits",
+        "double.rounding",       "double.guard",          "double.ulp.digits",
+        "double.neg.ulp.digits", "double.exponent",       "double.min.exp",
+        "double.max.exp",        "integer.max",           "sizeof.long",
+        "sizeof.longlong",       "sizeof.longdouble",     "sizeof.pointer"
+    };
+    // @formatter:on
+
+    private static RList createMachine() {
+        Object[] values = new Object[MACHINE_NAMES.length];
+        RAccuracyInfo acc = RAccuracyInfo.get();
+        values[0] = acc.eps;
+        values[1] = acc.epsneg;
+        values[2] = acc.xmin;
+        values[3] = acc.xmax;
+        values[4] = acc.ibeta;
+        values[5] = acc.it;
+        values[6] = acc.irnd;
+        values[7] = acc.ngrd;
+        values[8] = acc.machep;
+        values[9] = acc.negep;
+        values[10] = acc.iexp;
+        values[11] = acc.minexp;
+        values[12] = acc.maxexp;
+        values[13] = Integer.MAX_VALUE;
+        // TODO platform specific
+        values[14] = 8;
+        values[15] = 8;
+        values[16] = 16;
+        values[17] = 8;
+        return RDataFactory.createList(values, RDataFactory.createStringVector(MACHINE_NAMES, RDataFactory.COMPLETE_VECTOR));
+    }
+
 }
diff --git a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/Cat.java b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/Cat.java
index 647df679a6a28b6465c42883ac1168a66a41c801..315f81fdbf428dce68d3fc49754eb13449df8736 100644
--- a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/Cat.java
+++ b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/Cat.java
@@ -51,52 +51,42 @@ public abstract class Cat extends RInvisibleBuiltinNode {
     @Child private ToStringNode toString;
 
     @CompilationFinal private String currentSep;
+    @CompilationFinal private boolean sepContainsNewline;
 
     private void ensureToString(String sep) {
         if (toString == null || !sep.equals(currentSep)) {
             CompilerDirectives.transferToInterpreterAndInvalidate();
-            toString = insert(ToStringNodeFactory.create(null));
-            toString.setSeparator(sep);
-            toString.setQuotes(false);
-            toString.setIntL(false);
+            toString = insert(ToStringNodeFactory.create(null, false, sep, false));
+            sepContainsNewline = sep.contains("\n");
             currentSep = sep;
         }
     }
 
-    @Specialization
-    protected Object cat(RNull arg, String file, String sep, byte fill, Object labels, byte append) {
-        controlVisibility();
-        return RNull.instance;
-    }
-
     @Specialization
     protected RNull cat(RMissing arg, String file, String sep, byte fill, Object labels, byte append) {
         controlVisibility();
         return RNull.instance;
     }
 
-    @Specialization
-    protected RNull cat(VirtualFrame frame, RAbstractVector arg, String file, String sep, byte fill, Object labels, byte append) {
-        ensureToString(sep);
-        catIntl(toString.executeString(frame, arg));
-        controlVisibility();
-        return RNull.instance;
-    }
-
     @Specialization(guards = "!isNull")
     protected RNull cat(VirtualFrame frame, RArgsValuesAndNames args, String file, String sep, byte fill, Object labels, byte append) {
         ensureToString(sep);
         Object[] argValues = args.getValues();
         for (int i = 0; i < argValues.length; ++i) {
+            if (i > 0) {
+                catIntl(sep);
+            }
             catIntl(toString.executeString(frame, argValues[i]));
-            catSep(sep, argValues, i);
+        }
+        if (sepContainsNewline && argValues.length > 0) {
+            catIntl("\n");
         }
         controlVisibility();
         return RNull.instance;
     }
 
     @Specialization(guards = "isNull")
-    protected RNull catNull(VirtualFrame frame, RArgsValuesAndNames args, String file, String sep, byte fill, Object labels, byte append) {
+    protected RNull catNull(RArgsValuesAndNames args, String file, String sep, byte fill, Object labels, byte append) {
         controlVisibility();
         return RNull.instance;
     }
@@ -105,12 +95,6 @@ public abstract class Cat extends RInvisibleBuiltinNode {
         return args.length() == 1 && args.getValues()[0] == RNull.instance;
     }
 
-    private static void catSep(String sep, Object[] os, int j) {
-        if (j < os.length - 1 || sep.indexOf('\n') != -1) {
-            catIntl(sep);
-        }
-    }
-
     @TruffleBoundary
     private static void catIntl(String s) {
         RContext.getInstance().getConsoleHandler().print(s);
diff --git a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/Ceiling.java b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/Ceiling.java
index ec77a35651f656b6db78b858a5eea222f0c02f7c..3a218a2792dfc50663e32b9ebcdf5f203f3d76a8 100644
--- a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/Ceiling.java
+++ b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/Ceiling.java
@@ -40,6 +40,6 @@ public class Ceiling extends RWrapperBuiltinNode {
 
     @Override
     protected RNode createDelegate() {
-        return UnaryArithmeticNodeFactory.create(UnaryArithmetic.CEILING, this.getArguments()[0]);
+        return UnaryArithmeticNodeFactory.create(UnaryArithmetic.CEILING, RError.Message.NON_NUMERIC_MATH, getArguments()[0]);
     }
 }
diff --git a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/Complex.java b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/Complex.java
index fb26e7b12c854f1a893ebab755bf1ef829c2276f..8aceec86d6c3aa3c53e912fac6563e13b6f87c31 100644
--- a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/Complex.java
+++ b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/Complex.java
@@ -72,5 +72,4 @@ public abstract class Complex extends RBuiltinNode {
     protected static boolean zeroLength(int lengthOut, double real, double imaginary, int modulus, int argument) {
         return lengthOut == 0;
     }
-
 }
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 ca5a98df978e07a5cbfb2019a7da2c16b8f8332d..7f25664c2d321c74a2738117da7ce1d6ec08f2b9 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
@@ -38,6 +38,7 @@ import com.oracle.truffle.r.nodes.builtin.*;
 import com.oracle.truffle.r.runtime.*;
 import com.oracle.truffle.r.runtime.data.*;
 import com.oracle.truffle.r.runtime.data.model.*;
+import com.oracle.truffle.r.runtime.ffi.*;
 
 public class FileFunctions {
 
@@ -487,4 +488,51 @@ public class FileFunctions {
             return doXyzName(vec, basePathFunction);
         }
     }
+
+    @RBuiltin(name = "dir.create", kind = INTERNAL, parameterNames = {"path", "showWarnings", "recursive", "mode"})
+    public abstract static class DirCreate extends RInvisibleBuiltinNode {
+        @TruffleBoundary
+        @Specialization
+        protected byte dirCreate(RAbstractStringVector pathVec, byte showWarnings, byte recursive, RIntVector octMode) {
+            controlVisibility();
+            boolean ok = true;
+            if (pathVec.getLength() != 1) {
+                throw RError.error(getEncapsulatingSourceSection(), 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));
+            }
+            return RRuntime.asLogical(ok);
+        }
+
+        protected boolean mkparentdirs(File file, byte showWarnings, int mode) {
+            if (file.isDirectory()) {
+                return true;
+            }
+            if (file.exists()) {
+                return false;
+            }
+            if (mkparentdirs(file.getParentFile(), showWarnings, mode)) {
+                return mkdir(file.getAbsolutePath(), showWarnings, mode);
+            } else {
+                return false;
+            }
+        }
+
+        protected boolean mkdir(String path, byte showWarnings, int mode) {
+            try {
+                RFFIFactory.getRFFI().getBaseRFFI().mkdir(path, mode);
+                return true;
+            } catch (IOException ex) {
+                if (RRuntime.fromLogical(showWarnings)) {
+                    RContext.getInstance().setEvalWarning("cannot create dir '" + path + "'");
+                }
+                return false;
+            }
+        }
+    }
 }
diff --git a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/Floor.java b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/Floor.java
index dcb3e5e06de7c15f662abb650183f53953588739..a2ceda014336c1646bb1670fe22f44ebe70bbb17 100644
--- a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/Floor.java
+++ b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/Floor.java
@@ -40,6 +40,6 @@ public class Floor extends RWrapperBuiltinNode {
 
     @Override
     protected RNode createDelegate() {
-        return UnaryArithmeticNodeFactory.create(UnaryArithmetic.FLOOR, this.getArguments()[0]);
+        return UnaryArithmeticNodeFactory.create(UnaryArithmetic.FLOOR, RError.Message.NON_NUMERIC_MATH, getArguments()[0]);
     }
 }
diff --git a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/Inherits.java b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/Inherits.java
index 254cdf49e3e3f94bac724ae5e5224cc4c96f0677..5a00034f233844f4ed9ab24f93f42c6b8d02fc1b 100644
--- a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/Inherits.java
+++ b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/Inherits.java
@@ -62,16 +62,35 @@ public abstract class Inherits extends RBuiltinNode {
         return which != RRuntime.LOGICAL_TRUE;
     }
 
+    @SuppressWarnings("unused")
+    public boolean whichFalse(RConnection x, RAbstractStringVector what, byte which) {
+        return which != RRuntime.LOGICAL_TRUE;
+    }
+
     @Specialization(guards = "whichFalse")
     protected byte doInherits(VirtualFrame frame, RAbstractContainer x, RAbstractStringVector what, @SuppressWarnings("unused") byte which) {
         return initInheritsNode().execute(frame, x, what);
     }
 
+    @Specialization(guards = "whichFalse")
+    protected byte doInherits(VirtualFrame frame, RConnection x, RAbstractStringVector what, @SuppressWarnings("unused") byte which) {
+        return initInheritsNode().execute(frame, x, what);
+    }
+
+    @Specialization(guards = "!whichFalse")
+    protected Object doesInherit(RAbstractVector x, RAbstractStringVector what, @SuppressWarnings("unused") byte which) {
+        return doDoesInherit(x.getClassHierarchy(), what);
+    }
+
+    @Specialization(guards = "!whichFalse")
+    protected Object doesInherit(RConnection x, RAbstractStringVector what, @SuppressWarnings("unused") byte which) {
+        return doDoesInherit(x.getClassHierarchy(), what);
+    }
+
     @TruffleBoundary
     // map operations lead to recursion resulting in compilation failure
-    @Specialization(guards = "!whichFalse")
-    protected Object doesInherit(RAbstractContainer x, RAbstractStringVector what, @SuppressWarnings("unused") byte which) {
-        Map<String, Integer> classToPos = InheritsNode.initClassToPos(x);
+    private static Object doDoesInherit(RStringVector classHr, RAbstractStringVector what) {
+        Map<String, Integer> classToPos = InheritsNode.initClassToPos(classHr);
         int[] result = new int[what.getLength()];
         for (int i = 0; i < what.getLength(); ++i) {
             final Integer pos = classToPos.get(what.getDataAt(i));
@@ -82,5 +101,6 @@ public abstract class Inherits extends RBuiltinNode {
             }
         }
         return RDataFactory.createIntVector(result, true);
+
     }
 }
diff --git a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/NChar.java b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/NChar.java
index 20a56e8623ebb1587d91643ae0367ab28c9e55a9..8f1d252a39f7a9d1f6d1eec7d3dcb17ef3e590bf 100644
--- a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/NChar.java
+++ b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/NChar.java
@@ -31,7 +31,6 @@ import com.oracle.truffle.r.nodes.*;
 import com.oracle.truffle.r.nodes.access.*;
 import com.oracle.truffle.r.nodes.builtin.*;
 import com.oracle.truffle.r.nodes.unary.*;
-import com.oracle.truffle.r.nodes.unary.ConvertNode.ConversionFailedException;
 import com.oracle.truffle.r.runtime.*;
 import com.oracle.truffle.r.runtime.data.*;
 import com.oracle.truffle.r.runtime.data.model.*;
diff --git a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/NZChar.java b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/NZChar.java
index efaaeb97aa534302257ee00b0c7ecdcd1482b076..637ca46292c4f347d9f0597bdf96f026635775f7 100644
--- a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/NZChar.java
+++ b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/NZChar.java
@@ -29,7 +29,6 @@ import com.oracle.truffle.api.dsl.*;
 import com.oracle.truffle.api.frame.*;
 import com.oracle.truffle.r.nodes.builtin.*;
 import com.oracle.truffle.r.nodes.unary.*;
-import com.oracle.truffle.r.nodes.unary.ConvertNode.ConversionFailedException;
 import com.oracle.truffle.r.runtime.*;
 import com.oracle.truffle.r.runtime.data.*;
 import com.oracle.truffle.r.runtime.data.model.*;
diff --git a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/R/character.R b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/R/character.R
index b49ea5aac52f51310ba616bd1848d281f187c88b..c5f6904a3440d1f0b8a6956f7b10916dc888da9a 100644
--- a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/R/character.R
+++ b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/R/character.R
@@ -189,6 +189,6 @@ sQuote <- function(x)
 #  paste0(before, x, after)
 #}
 #
-#strtoi <-
-#    function(x, base = 0L)
-#  .Internal(strtoi(as.character(x), as.integer(base)))
+strtoi <-
+    function(x, base = 0L)
+  .Internal(strtoi(as.character(x), as.integer(base)))
diff --git a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/R/octhex.R b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/R/octhex.R
new file mode 100644
index 0000000000000000000000000000000000000000..bf4f3b8b14bcf485e19685f4d8957b7a0e5a4a15
--- /dev/null
+++ b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/R/octhex.R
@@ -0,0 +1,127 @@
+#  File src/library/base/R/octhex.R
+#  Part of the R package, http://www.R-project.org
+#
+#  Copyright (C) 1995-2012 The R Core Team
+#
+#  This program is free software; you can redistribute it and/or modify
+#  it under the terms of the GNU General Public License as published by
+#  the Free Software Foundation; either version 2 of the License, or
+#  (at your option) any later version.
+#
+#  This program is distributed in the hope that it will be useful,
+#  but WITHOUT ANY WARRANTY; without even the implied warranty of
+#  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+#  GNU General Public License for more details.
+#
+#  A copy of the GNU General Public License is available at
+#  http://www.r-project.org/Licenses/
+
+format.octmode <- function(x, width = NULL, ...)
+{
+	isna <- is.na(x)
+	y <- as.integer(x[!isna])
+	fmt <- if(!is.null(width)) paste0("%0", width, "o") else "%o"
+	ans <- rep.int(NA_character_, length(x))
+	ans0 <- sprintf(fmt, y)
+	if(is.null(width) && length(y) > 1L) {
+		## previous version padded with zeroes to a common field width
+		nc <- max(nchar(ans0))
+		ans0 <- sprintf(paste0("%0", nc, "o"), y)
+	}
+	ans[!isna] <- ans0
+	dim(ans) <- dim(x)
+	dimnames(ans) <- dimnames(x)
+	names(ans) <- names(x)
+	ans
+}
+
+as.character.octmode <- function(x, ...) format.octmode(x, ...)
+
+print.octmode <- function(x, ...)
+{
+	print(format(x), ...)
+	invisible(x)
+}
+
+`[.octmode` <- function (x, i)
+{
+	cl <- oldClass(x)
+	y <- NextMethod("[")
+	oldClass(y) <- cl
+	y
+}
+
+as.octmode <- function(x)
+{
+	if(inherits(x, "octmode")) return(x)
+	if(is.double(x) && x == as.integer(x)) x <- as.integer(x)
+	if(is.integer(x)) return(structure(x, class="octmode"))
+	if(is.character(x)) {
+		z <- strtoi(x, 8L)
+		if(!any(is.na(z) | z < 0)) return(structure(z, class="octmode"))
+	}
+	stop("'x' cannot be coerced to class \"octmode\"")
+}
+
+## BioC packages cellHTS2 and flowCore misuse this for doubles,
+## hence the as.integer() call
+format.hexmode <- function(x, width = NULL, upper.case = FALSE, ...)
+{
+	isna <- is.na(x)
+	y <- as.integer(x[!isna])
+	fmt0 <- if(upper.case) "X" else "x"
+	fmt <- if(!is.null(width)) paste0("%0", width, fmt0) else paste0("%", fmt0)
+	ans <- rep.int(NA_character_, length(x))
+	ans0 <- sprintf(fmt, y)
+	if(is.null(width) && length(y) > 1L) {
+		## previous version padded with zeroes to a common field width
+		nc <- max(nchar(ans0))
+		ans0 <- sprintf(paste0("%0", nc, fmt0), y)
+	}
+	ans[!isna] <- ans0
+	dim(ans) <- dim(x)
+	dimnames(ans) <- dimnames(x)
+	names(ans) <- names(x)
+	ans
+}
+
+as.character.hexmode <- function(x, ...) format.hexmode(x, ...)
+
+print.hexmode <- function(x, ...)
+{
+	print(format(x), ...)
+	invisible(x)
+}
+
+`[.hexmode` <- function (x, i)
+{
+	cl <- oldClass(x)
+	y <- NextMethod("[")
+	oldClass(y) <- cl
+	y
+}
+
+as.hexmode <- function(x)
+{
+	if(inherits(x, "hexmode")) return(x)
+	if(is.double(x) && (x == as.integer(x))) x <- as.integer(x)
+	if(is.integer(x)) return(structure(x, class = "hexmode"))
+	if(is.character(x)) {
+		z <- strtoi(x, 16L)
+		if(!any(is.na(z) | z < 0)) return(structure(z, class = "hexmode"))
+	}
+	stop("'x' cannot be coerced to class \"hexmode\"")
+}
+
+
+`!.octmode` <- function(a) as.octmode(bitwNot(as.octmode(a)))
+
+`&.octmode` <- function(a, b) as.octmode(bitwAnd(as.octmode(a), as.octmode(b)))
+`|.octmode` <- function(a, b) as.octmode(bitwOr(as.octmode(a), as.octmode(b)))
+xor.octmode <- function(a, b) as.octmode(bitwXor(as.octmode(a), as.octmode(b)))
+
+`!.hexmode` <- function(a) as.hexmode(bitwNot(as.hexmode(a)))
+
+`&.hexmode` <- function(a, b) as.hexmode(bitwAnd(as.hexmode(a), as.hexmode(b)))
+`|.hexmode` <- function(a, b) as.hexmode(bitwOr(as.hexmode(a), as.hexmode(b)))
+xor.hexmode <- function(a, b) as.hexmode(bitwXor(as.hexmode(a), as.hexmode(b)))
diff --git a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/SortFunctions.java b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/SortFunctions.java
index 1e71255970ca752ae45fe1f56ffc88a53e27e0d3..f4271c3513fcc153107bfb3918dfdd8c2d85dbab 100644
--- a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/SortFunctions.java
+++ b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/SortFunctions.java
@@ -53,6 +53,7 @@ public class SortFunctions {
     // TODO Implement in R
     public abstract static class SortList extends RBuiltinNode {
         private final ConditionProfile orderProfile = ConditionProfile.createBinaryProfile();
+
         @Override
         public RNode[] getParameterValues() {
             return new RNode[]{ConstantNode.create(RMissing.instance), ConstantNode.create(RNull.instance), ConstantNode.create(RRuntime.LOGICAL_TRUE), ConstantNode.create(RRuntime.LOGICAL_FALSE),
diff --git a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/Strtoi.java b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/Strtoi.java
new file mode 100644
index 0000000000000000000000000000000000000000..968f323d7cb2f34e0e36318408029478a5a3aacb
--- /dev/null
+++ b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/Strtoi.java
@@ -0,0 +1,75 @@
+/*
+ * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package com.oracle.truffle.r.nodes.builtin.base;
+
+import com.oracle.truffle.api.CompilerDirectives.TruffleBoundary;
+import com.oracle.truffle.api.dsl.*;
+import com.oracle.truffle.r.nodes.builtin.*;
+import com.oracle.truffle.r.runtime.*;
+import com.oracle.truffle.r.runtime.data.*;
+import com.oracle.truffle.r.runtime.data.model.*;
+import com.oracle.truffle.r.runtime.ffi.*;
+
+@RBuiltin(name = "strtoi", kind = RBuiltinKind.INTERNAL, parameterNames = {"x", "base"})
+public abstract class Strtoi extends RBuiltinNode {
+    @TruffleBoundary
+    @Specialization
+    protected RIntVector doStrtoi(RAbstractStringVector vec, int baseArg) {
+        int base = baseArg;
+        int[] data = new int[vec.getLength()];
+        boolean complete = RDataFactory.COMPLETE_VECTOR;
+        for (int i = 0; i < data.length; i++) {
+            int dataValue = RRuntime.INT_NA;
+            try {
+                String s = vec.getDataAt(i);
+                if (s.length() == 0) {
+                    complete = RDataFactory.INCOMPLETE_VECTOR;
+                } else {
+                    if (base == 0) {
+                        char ch0 = s.charAt(0);
+                        if (ch0 == '0') {
+                            if (s.length() > 1 && (s.charAt(1) == 'x' || s.charAt(1) == 'X')) {
+                                base = 16;
+                            } else {
+                                base = 8;
+                            }
+                        } else {
+                            base = 10;
+                        }
+                    }
+                    long value = RFFIFactory.getRFFI().getBaseRFFI().strtol(s, base);
+                    if (value > Integer.MAX_VALUE || value < Integer.MIN_VALUE) {
+                        complete = RDataFactory.INCOMPLETE_VECTOR;
+                    } else {
+                        dataValue = (int) value;
+                    }
+                }
+            } catch (IllegalArgumentException ex) {
+                complete = RDataFactory.INCOMPLETE_VECTOR;
+            }
+            data[i] = dataValue;
+        }
+        return RDataFactory.createIntVector(data, complete);
+    }
+
+}
diff --git a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/Vector.java b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/Vector.java
index a86cc41c076bb2d8b3d2560e9848cce0b913b807..3496b68623a38ad5c7cc75c9a61f6036fbb5281e 100644
--- a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/Vector.java
+++ b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/Vector.java
@@ -27,6 +27,7 @@ import static com.oracle.truffle.r.runtime.RBuiltinKind.*;
 import java.util.*;
 
 import com.oracle.truffle.api.dsl.*;
+import com.oracle.truffle.api.utilities.*;
 import com.oracle.truffle.r.nodes.*;
 import com.oracle.truffle.r.nodes.access.*;
 import com.oracle.truffle.r.nodes.builtin.*;
@@ -38,6 +39,8 @@ import com.oracle.truffle.r.runtime.data.model.*;
 @RBuiltin(name = "vector", kind = INTERNAL, parameterNames = {"mode", "length"})
 public abstract class Vector extends RBuiltinNode {
 
+    private final ValueProfile modeProfile = ValueProfile.createIdentityProfile();
+
     @Override
     public RNode[] getParameterValues() {
         // mode = "logical", length = 0
@@ -54,7 +57,7 @@ public abstract class Vector extends RBuiltinNode {
     @Specialization
     protected RAbstractVector vector(String mode, int length) {
         controlVisibility();
-        switch (mode) {
+        switch (modeProfile.profile(mode)) {
             case "character":
                 return RDataFactory.createStringVector(length);
             case "logical":
@@ -72,5 +75,4 @@ public abstract class Vector extends RBuiltinNode {
                 throw RError.error(getEncapsulatingSourceSection(), RError.Message.CANNOT_MAKE_VECTOR_OF_MODE, mode);
         }
     }
-
 }
diff --git a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/binary/BinaryArithmeticNode.java b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/binary/BinaryArithmeticNode.java
index e2ad8848392a05547be2cc6afc3acba416997dc3..3b2e1647c639918a561c3c1d97aafa85331bdc0f 100644
--- a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/binary/BinaryArithmeticNode.java
+++ b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/binary/BinaryArithmeticNode.java
@@ -73,7 +73,7 @@ public abstract class BinaryArithmeticNode extends RBuiltinNode {
                 throw RError.error(getSourceSection(), RError.Message.ARGUMENT_EMPTY, 2);
             } else {
                 CompilerDirectives.transferToInterpreterAndInvalidate();
-                unaryNode = insert(UnaryArithmeticNodeFactory.create(unaryFactory, null));
+                unaryNode = insert(UnaryArithmeticNodeFactory.create(unaryFactory, RError.Message.INVALID_ARG_TYPE_UNARY, null));
             }
         }
         return unaryNode;
diff --git a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/unary/CastComplexNode.java b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/unary/CastComplexNode.java
index bf0e12563d7c088c68f28c7fd7a8de400fb30a9a..1e38b21933e742c4b75757cc2657a260e4b2e44b 100644
--- a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/unary/CastComplexNode.java
+++ b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/unary/CastComplexNode.java
@@ -22,10 +22,12 @@
  */
 package com.oracle.truffle.r.nodes.unary;
 
+import java.util.function.*;
+
 import com.oracle.truffle.api.CompilerDirectives.TruffleBoundary;
 import com.oracle.truffle.api.dsl.*;
 import com.oracle.truffle.api.frame.*;
-import com.oracle.truffle.r.nodes.unary.ConvertNode.ConversionFailedException;
+import com.oracle.truffle.api.utilities.*;
 import com.oracle.truffle.r.runtime.*;
 import com.oracle.truffle.r.runtime.data.*;
 import com.oracle.truffle.r.runtime.data.model.*;
@@ -34,6 +36,7 @@ import com.oracle.truffle.r.runtime.ops.na.*;
 public abstract class CastComplexNode extends CastNode {
 
     private final NACheck naCheck = NACheck.create();
+    private final BranchProfile warningBranch = BranchProfile.create();
 
     public abstract Object executeComplex(VirtualFrame frame, int o);
 
@@ -81,149 +84,54 @@ public abstract class CastComplexNode extends CastNode {
         naCheck.enable(operand);
         RComplex result = naCheck.convertStringToComplex(operand);
         if (RRuntime.isNA(result)) {
+            warningBranch.enter();
             RError.warning(RError.Message.NA_INTRODUCED_COERCION);
         }
         return result;
     }
 
-    private double[] dataFromLogical(RLogicalVector operand) {
-        naCheck.enable(operand);
-        double[] ddata = new double[operand.getLength() << 1];
-        for (int i = 0; i < operand.getLength(); i++) {
-            byte value = operand.getDataAt(i);
-            RComplex complexValue = naCheck.convertLogicalToComplex(value);
-            int index = i << 1;
-            ddata[index] = complexValue.getRealPart();
-            ddata[index + 1] = complexValue.getImaginaryPart();
-        }
-        return ddata;
-    }
-
-    private double[] dataFromString(RStringVector operand) {
+    private RComplexVector createResultVector(RAbstractVector operand, IntFunction<RComplex> elementFunction) {
         naCheck.enable(operand);
         double[] ddata = new double[operand.getLength() << 1];
         for (int i = 0; i < operand.getLength(); i++) {
-            String value = operand.getDataAt(i);
-            RComplex complexValue = naCheck.convertStringToComplex(value);
-            if (RRuntime.isNA(complexValue)) {
-                RError.warning(RError.Message.NA_INTRODUCED_COERCION);
-            }
+            RComplex complexValue = elementFunction.apply(i);
             int index = i << 1;
             ddata[index] = complexValue.getRealPart();
             ddata[index + 1] = complexValue.getImaginaryPart();
         }
-        return ddata;
-    }
-
-    private static double[] dataFromRaw(RRawVector operand) {
-        double[] ddata = new double[operand.getLength() << 1];
-        for (int i = 0; i < operand.getLength(); i++) {
-            byte value = operand.getDataAt(i).getValue();
-            int index = i << 1;
-            ddata[index] = value;
-            ddata[index + 1] = 0;
-        }
-        return ddata;
-    }
-
-    @Specialization
-    protected RComplexVector doIntVector(RIntVector operand) {
-        return performAbstractIntVector(operand);
-    }
-
-    @Specialization
-    protected RComplexVector doIntSequence(RIntSequence operand) {
-        return performAbstractIntVector(operand);
-    }
-
-    @Specialization(guards = {"!preserveNames", "preserveDimensions"})
-    protected RComplexVector doLogicalVectorDims(RLogicalVector operand) {
-        double[] ddata = dataFromLogical(operand);
-        RComplexVector ret = RDataFactory.createComplexVector(ddata, naCheck.neverSeenNA(), operand.getDimensions());
-        if (isAttrPreservation()) {
-            ret.copyRegAttributesFrom(operand);
-        }
-        return ret;
-    }
-
-    @Specialization(guards = {"preserveNames", "!preserveDimensions"})
-    protected RComplexVector doLogicalVectorNames(RLogicalVector operand) {
-        double[] ddata = dataFromLogical(operand);
-        RComplexVector ret = RDataFactory.createComplexVector(ddata, naCheck.neverSeenNA(), operand.getNames());
-        if (isAttrPreservation()) {
-            ret.copyRegAttributesFrom(operand);
-        }
-        return ret;
-    }
-
-    @Specialization(guards = {"preserveNames", "preserveDimensions"})
-    protected RComplexVector doLogicalVectorDimsNames(RLogicalVector operand) {
-        double[] ddata = dataFromLogical(operand);
-        RComplexVector ret = RDataFactory.createComplexVector(ddata, naCheck.neverSeenNA(), operand.getDimensions(), operand.getNames());
-        if (isAttrPreservation()) {
-            ret.copyRegAttributesFrom(operand);
-        }
-        return ret;
-    }
-
-    @Specialization(guards = {"!preserveNames", "!preserveDimensions"})
-    protected RComplexVector doLogicalVector(RLogicalVector operand) {
-        double[] ddata = dataFromLogical(operand);
-        RComplexVector ret = RDataFactory.createComplexVector(ddata, naCheck.neverSeenNA());
-        if (isAttrPreservation()) {
-            ret.copyRegAttributesFrom(operand);
-        }
-        return ret;
-    }
-
-    @Specialization(guards = {"!preserveNames", "preserveDimensions"})
-    protected RComplexVector doStringVectorDims(RStringVector operand) {
-        double[] ddata = dataFromString(operand);
-        RComplexVector ret = RDataFactory.createComplexVector(ddata, naCheck.neverSeenNA(), operand.getDimensions());
-        if (isAttrPreservation()) {
-            ret.copyRegAttributesFrom(operand);
-        }
-        return ret;
-    }
-
-    @Specialization(guards = {"preserveNames", "!preserveDimensions"})
-    protected RComplexVector doStringVectorNames(RStringVector operand) {
-        double[] ddata = dataFromString(operand);
-        RComplexVector ret = RDataFactory.createComplexVector(ddata, naCheck.neverSeenNA(), operand.getNames());
+        RComplexVector ret = RDataFactory.createComplexVector(ddata, naCheck.neverSeenNA(), isPreserveDimensions() ? operand.getDimensions() : null, isPreserveNames() ? operand.getNames() : null);
         if (isAttrPreservation()) {
             ret.copyRegAttributesFrom(operand);
         }
         return ret;
     }
 
-    @Specialization(guards = {"preserveNames", "preserveDimensions"})
-    protected RComplexVector doStringVectorDimsNames(RStringVector operand) {
-        double[] ddata = dataFromString(operand);
-        RComplexVector ret = RDataFactory.createComplexVector(ddata, naCheck.neverSeenNA(), operand.getDimensions(), operand.getNames());
-        if (isAttrPreservation()) {
-            ret.copyRegAttributesFrom(operand);
-        }
-        return ret;
+    @Specialization
+    protected RComplexVector doIntVector(RAbstractIntVector operand) {
+        return createResultVector(operand, index -> naCheck.convertIntToComplex(operand.getDataAt(index)));
     }
 
-    @Specialization(guards = {"!preserveNames", "!preserveDimensions"})
-    protected RComplexVector doStringVector(RStringVector operand) {
-        double[] ddata = dataFromString(operand);
-        RComplexVector ret = RDataFactory.createComplexVector(ddata, naCheck.neverSeenNA());
-        if (isAttrPreservation()) {
-            ret.copyRegAttributesFrom(operand);
-        }
-        return ret;
+    @Specialization
+    protected RComplexVector doDoubleVector(RAbstractDoubleVector operand) {
+        return createResultVector(operand, index -> naCheck.convertDoubleToComplex(operand.getDataAt(index)));
     }
 
     @Specialization
-    protected RComplexVector doDoubleVector(RDoubleVector operand) {
-        return performAbstractDoubleVector(operand);
+    protected RComplexVector doLogicalVector(RLogicalVector operand) {
+        return createResultVector(operand, index -> naCheck.convertLogicalToComplex(operand.getDataAt(index)));
     }
 
     @Specialization
-    protected RComplexVector doDoubleSequence(RDoubleSequence operand) {
-        return performAbstractDoubleVector(operand);
+    protected RComplexVector doStringVector(RStringVector operand) {
+        return createResultVector(operand, index -> {
+            String value = operand.getDataAt(index);
+            RComplex complexValue = naCheck.convertStringToComplex(value);
+            if (RRuntime.isNA(complexValue)) {
+                warningBranch.enter();
+                RError.warning(RError.Message.NA_INTRODUCED_COERCION);
+            }
+            return complexValue;
+        });
     }
 
     @Specialization
@@ -231,44 +139,9 @@ public abstract class CastComplexNode extends CastNode {
         return vector;
     }
 
-    @Specialization(guards = {"!preserveNames", "preserveDimensions"})
-    protected RComplexVector doRawVectorDims(RRawVector operand) {
-        double[] ddata = dataFromRaw(operand);
-        RComplexVector ret = RDataFactory.createComplexVector(ddata, RDataFactory.COMPLETE_VECTOR, operand.getDimensions());
-        if (isAttrPreservation()) {
-            ret.copyRegAttributesFrom(operand);
-        }
-        return ret;
-    }
-
-    @Specialization(guards = {"preserveNames", "!preserveDimensions"})
-    protected RComplexVector doRawVectorNames(RRawVector operand) {
-        double[] ddata = dataFromRaw(operand);
-        RComplexVector ret = RDataFactory.createComplexVector(ddata, RDataFactory.COMPLETE_VECTOR, operand.getNames());
-        if (isAttrPreservation()) {
-            ret.copyRegAttributesFrom(operand);
-        }
-        return ret;
-    }
-
-    @Specialization(guards = {"preserveNames", "preserveDimensions"})
-    protected RComplexVector doRawVectorDimsNames(RRawVector operand) {
-        double[] ddata = dataFromRaw(operand);
-        RComplexVector ret = RDataFactory.createComplexVector(ddata, RDataFactory.COMPLETE_VECTOR, operand.getDimensions(), operand.getNames());
-        if (isAttrPreservation()) {
-            ret.copyRegAttributesFrom(operand);
-        }
-        return ret;
-    }
-
-    @Specialization(guards = {"!preserveNames", "!preserveDimensions"})
+    @Specialization
     protected RComplexVector doRawVector(RRawVector operand) {
-        double[] ddata = dataFromRaw(operand);
-        RComplexVector ret = RDataFactory.createComplexVector(ddata, RDataFactory.COMPLETE_VECTOR);
-        if (isAttrPreservation()) {
-            ret.copyRegAttributesFrom(operand);
-        }
-        return ret;
+        return createResultVector(operand, index -> RDataFactory.createComplex(operand.getDataAt(index).getValue(), 0));
     }
 
     @Fallback
@@ -276,57 +149,4 @@ public abstract class CastComplexNode extends CastNode {
     public int doOther(Object operand) {
         throw new ConversionFailedException(operand.getClass().getName());
     }
-
-    private RComplexVector performAbstractIntVector(RAbstractIntVector operand) {
-        naCheck.enable(operand);
-        double[] ddata = new double[operand.getLength() << 1];
-        for (int i = 0; i < operand.getLength(); i++) {
-            int value = operand.getDataAt(i);
-            RComplex complexValue = naCheck.convertIntToComplex(value);
-            int index = i << 1;
-            ddata[index] = complexValue.getRealPart();
-            ddata[index + 1] = complexValue.getImaginaryPart();
-        }
-        RComplexVector ret;
-        if (preserveDimensions() && preserveNames()) {
-            ret = RDataFactory.createComplexVector(ddata, naCheck.neverSeenNA(), operand.getDimensions(), operand.getNames());
-        } else if (preserveDimensions()) {
-            ret = RDataFactory.createComplexVector(ddata, naCheck.neverSeenNA(), operand.getDimensions());
-        } else if (preserveNames()) {
-            ret = RDataFactory.createComplexVector(ddata, naCheck.neverSeenNA(), operand.getNames());
-        } else {
-            ret = RDataFactory.createComplexVector(ddata, naCheck.neverSeenNA());
-        }
-        if (isAttrPreservation()) {
-            ret.copyRegAttributesFrom(operand);
-        }
-        return ret;
-    }
-
-    private RComplexVector performAbstractDoubleVector(RAbstractDoubleVector operand) {
-        naCheck.enable(operand);
-        double[] ddata = new double[operand.getLength() << 1];
-        for (int i = 0; i < operand.getLength(); i++) {
-            double value = operand.getDataAt(i);
-            RComplex complexValue = naCheck.convertDoubleToComplex(value);
-            int index = i << 1;
-            ddata[index] = complexValue.getRealPart();
-            ddata[index + 1] = complexValue.getImaginaryPart();
-        }
-        RComplexVector ret;
-        if (preserveDimensions() && preserveNames()) {
-            ret = RDataFactory.createComplexVector(ddata, naCheck.neverSeenNA(), operand.getDimensions(), operand.getNames());
-        } else if (preserveDimensions()) {
-            ret = RDataFactory.createComplexVector(ddata, naCheck.neverSeenNA(), operand.getDimensions());
-        } else if (preserveNames()) {
-            ret = RDataFactory.createComplexVector(ddata, naCheck.neverSeenNA(), operand.getNames());
-        } else {
-            ret = RDataFactory.createComplexVector(ddata, naCheck.neverSeenNA());
-        }
-        if (isAttrPreservation()) {
-            ret.copyRegAttributesFrom(operand);
-        }
-        return ret;
-    }
-
 }
diff --git a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/unary/CastDoubleNode.java b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/unary/CastDoubleNode.java
index dec31f20a779fb164d1cb33468436064988a13fb..525d98a651664f5edac5003bcd4df612a07c7cc5 100644
--- a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/unary/CastDoubleNode.java
+++ b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/unary/CastDoubleNode.java
@@ -22,11 +22,13 @@
  */
 package com.oracle.truffle.r.nodes.unary;
 
+import java.util.function.*;
+
 import com.oracle.truffle.api.*;
 import com.oracle.truffle.api.CompilerDirectives.TruffleBoundary;
 import com.oracle.truffle.api.dsl.*;
 import com.oracle.truffle.api.frame.*;
-import com.oracle.truffle.r.nodes.unary.ConvertNode.ConversionFailedException;
+import com.oracle.truffle.api.utilities.*;
 import com.oracle.truffle.r.runtime.*;
 import com.oracle.truffle.r.runtime.data.*;
 import com.oracle.truffle.r.runtime.data.model.*;
@@ -35,6 +37,7 @@ import com.oracle.truffle.r.runtime.ops.na.*;
 public abstract class CastDoubleNode extends CastNode {
 
     private final NACheck naCheck = NACheck.create();
+    private final BranchProfile warningBranch = BranchProfile.create();
 
     public abstract Object executeDouble(VirtualFrame frame, int o);
 
@@ -49,7 +52,7 @@ public abstract class CastDoubleNode extends CastNode {
     private Object castDoubleRecursive(VirtualFrame frame, Object o) {
         if (recursiveCastDouble == null) {
             CompilerDirectives.transferToInterpreterAndInvalidate();
-            recursiveCastDouble = insert(CastDoubleNodeFactory.create(null, isNamesPreservation(), isDimensionsPreservation(), isAttrPreservation()));
+            recursiveCastDouble = insert(CastDoubleNodeFactory.create(null, isPreserveNames(), isDimensionsPreservation(), isAttrPreservation()));
         }
         return recursiveCastDouble.executeDouble(frame, o);
     }
@@ -75,6 +78,7 @@ public abstract class CastDoubleNode extends CastNode {
         naCheck.enable(operand);
         double result = naCheck.convertComplexToDouble(operand);
         if (operand.getImaginaryPart() != 0.0) {
+            warningBranch.enter();
             RError.warning(RError.Message.IMAGINARY_PARTS_DISCARDED_IN_COERCION);
         }
         return result;
@@ -91,6 +95,7 @@ public abstract class CastDoubleNode extends CastNode {
         naCheck.enable(operand);
         double result = naCheck.convertStringToDouble(operand);
         if (isNA(result)) {
+            warningBranch.enter();
             RError.warning(RError.Message.NA_INTRODUCED_COERCION);
         }
         return result;
@@ -101,17 +106,35 @@ public abstract class CastDoubleNode extends CastNode {
         return RRuntime.raw2double(operand);
     }
 
-    private double[] dataFromLogical(RLogicalVector operand) {
+    private RDoubleVector createResultVector(RAbstractVector operand, double[] ddata) {
+        RDoubleVector ret = RDataFactory.createDoubleVector(ddata, naCheck.neverSeenNA(), isPreserveDimensions() ? operand.getDimensions() : null, isPreserveNames() ? operand.getNames() : null);
+        if (isAttrPreservation()) {
+            ret.copyRegAttributesFrom(operand);
+        }
+        return ret;
+    }
+
+    private RDoubleVector createResultVector(RAbstractVector operand, IntToDoubleFunction elementFunction) {
         naCheck.enable(operand);
         double[] ddata = new double[operand.getLength()];
         for (int i = 0; i < operand.getLength(); i++) {
-            byte value = operand.getDataAt(i);
-            ddata[i] = naCheck.convertLogicalToDouble(value);
+            ddata[i] = elementFunction.applyAsDouble(i);
         }
-        return ddata;
+        return createResultVector(operand, ddata);
     }
 
-    private double[] dataFromString(RStringVector operand) {
+    @Specialization
+    protected RDoubleVector doIntVector(RAbstractIntVector operand) {
+        return createResultVector(operand, index -> naCheck.convertIntToDouble(operand.getDataAt(index)));
+    }
+
+    @Specialization
+    protected RDoubleVector doLogicalVectorDims(RLogicalVector operand) {
+        return createResultVector(operand, index -> naCheck.convertLogicalToDouble(operand.getDataAt(index)));
+    }
+
+    @Specialization
+    protected RDoubleVector doStringVector(RStringVector operand) {
         naCheck.enable(operand);
         double[] ddata = new double[operand.getLength()];
         boolean warning = false;
@@ -123,21 +146,14 @@ public abstract class CastDoubleNode extends CastNode {
             }
         }
         if (warning) {
+            warningBranch.enter();
             RError.warning(RError.Message.NA_INTRODUCED_COERCION);
         }
-        return ddata;
-    }
-
-    private static double[] dataFromRaw(RRawVector operand) {
-        double[] ddata = new double[operand.getLength()];
-        for (int i = 0; i < operand.getLength(); i++) {
-            RRaw value = operand.getDataAt(i);
-            ddata[i] = RRuntime.raw2double(value);
-        }
-        return ddata;
+        return createResultVector(operand, ddata);
     }
 
-    private double[] dataFromComplex(RComplexVector operand) {
+    @Specialization
+    protected RDoubleVector doComplexVector(RComplexVector operand) {
         naCheck.enable(operand);
         double[] ddata = new double[operand.getLength()];
         boolean warning = false;
@@ -149,179 +165,15 @@ public abstract class CastDoubleNode extends CastNode {
             }
         }
         if (warning) {
+            warningBranch.enter();
             RError.warning(RError.Message.IMAGINARY_PARTS_DISCARDED_IN_COERCION);
         }
-        return ddata;
-    }
-
-    @Specialization
-    protected RDoubleVector doIntVector(RIntVector operand) {
-        return performAbstractIntVector(operand);
+        return createResultVector(operand, ddata);
     }
 
     @Specialization
-    protected RDoubleVector doIntVector(RIntSequence operand) {
-        return performAbstractIntVector(operand);
-    }
-
-    @Specialization(guards = {"!preserveNames", "preserveDimensions"})
-    protected RDoubleVector doLogicalVectorDims(RLogicalVector operand) {
-        double[] ddata = dataFromLogical(operand);
-        RDoubleVector ret = RDataFactory.createDoubleVector(ddata, naCheck.neverSeenNA(), operand.getDimensions());
-        if (isAttrPreservation()) {
-            ret.copyRegAttributesFrom(operand);
-        }
-        return ret;
-    }
-
-    @Specialization(guards = {"preserveNames", "!preserveDimensions"})
-    protected RDoubleVector doLogicalVectorNames(RLogicalVector operand) {
-        double[] ddata = dataFromLogical(operand);
-        RDoubleVector ret = RDataFactory.createDoubleVector(ddata, naCheck.neverSeenNA(), operand.getNames());
-        if (isAttrPreservation()) {
-            ret.copyRegAttributesFrom(operand);
-        }
-        return ret;
-    }
-
-    @Specialization(guards = {"preserveNames", "preserveDimensions"})
-    protected RDoubleVector doLogicalVectorDimsNames(RLogicalVector operand) {
-        double[] ddata = dataFromLogical(operand);
-        RDoubleVector ret = RDataFactory.createDoubleVector(ddata, naCheck.neverSeenNA(), operand.getDimensions(), operand.getNames());
-        if (isAttrPreservation()) {
-            ret.copyRegAttributesFrom(operand);
-        }
-        return ret;
-    }
-
-    @Specialization(guards = {"!preserveNames", "!preserveDimensions"})
-    protected RDoubleVector doLogicalVector(RLogicalVector operand) {
-        double[] ddata = dataFromLogical(operand);
-        RDoubleVector ret = RDataFactory.createDoubleVector(ddata, naCheck.neverSeenNA());
-        if (isAttrPreservation()) {
-            ret.copyRegAttributesFrom(operand);
-        }
-        return ret;
-    }
-
-    @Specialization(guards = {"!preserveNames", "preserveDimensions"})
-    protected RDoubleVector doStringVectorDims(RStringVector operand) {
-        double[] ddata = dataFromString(operand);
-        RDoubleVector ret = RDataFactory.createDoubleVector(ddata, naCheck.neverSeenNA(), operand.getDimensions());
-        if (isAttrPreservation()) {
-            ret.copyRegAttributesFrom(operand);
-        }
-        return ret;
-    }
-
-    @Specialization(guards = {"preserveNames", "!preserveDimensions"})
-    protected RDoubleVector doStringVectorNames(RStringVector operand) {
-        double[] ddata = dataFromString(operand);
-        RDoubleVector ret = RDataFactory.createDoubleVector(ddata, naCheck.neverSeenNA(), operand.getNames());
-        if (isAttrPreservation()) {
-            ret.copyRegAttributesFrom(operand);
-        }
-        return ret;
-    }
-
-    @Specialization(guards = {"preserveNames", "preserveDimensions"})
-    protected RDoubleVector doStringVectorDimsNames(RStringVector operand) {
-        double[] ddata = dataFromString(operand);
-        RDoubleVector ret = RDataFactory.createDoubleVector(ddata, naCheck.neverSeenNA(), operand.getDimensions(), operand.getNames());
-        if (isAttrPreservation()) {
-            ret.copyRegAttributesFrom(operand);
-        }
-        return ret;
-    }
-
-    @Specialization(guards = {"!preserveNames", "!preserveDimensions"})
-    protected RDoubleVector doStringVector(RStringVector operand) {
-        double[] ddata = dataFromString(operand);
-        RDoubleVector ret = RDataFactory.createDoubleVector(ddata, naCheck.neverSeenNA());
-        if (isAttrPreservation()) {
-            ret.copyRegAttributesFrom(operand);
-        }
-        return ret;
-    }
-
-    @Specialization(guards = {"!preserveNames", "preserveDimensions"})
-    protected RDoubleVector doComplexVectorDims(RComplexVector operand) {
-        double[] ddata = dataFromComplex(operand);
-        RDoubleVector ret = RDataFactory.createDoubleVector(ddata, naCheck.neverSeenNA(), operand.getDimensions());
-        if (isAttrPreservation()) {
-            ret.copyRegAttributesFrom(operand);
-        }
-        return ret;
-    }
-
-    @Specialization(guards = {"preserveNames", "!preserveDimensions"})
-    protected RDoubleVector doComplexVectorNames(RComplexVector operand) {
-        double[] ddata = dataFromComplex(operand);
-        RDoubleVector ret = RDataFactory.createDoubleVector(ddata, naCheck.neverSeenNA(), operand.getNames());
-        if (isAttrPreservation()) {
-            ret.copyRegAttributesFrom(operand);
-        }
-        return ret;
-    }
-
-    @Specialization(guards = {"preserveNames", "preserveDimensions"})
-    protected RDoubleVector doComplexVectorDimsNames(RComplexVector operand) {
-        double[] ddata = dataFromComplex(operand);
-        RDoubleVector ret = RDataFactory.createDoubleVector(ddata, naCheck.neverSeenNA(), operand.getDimensions(), operand.getNames());
-        if (isAttrPreservation()) {
-            ret.copyRegAttributesFrom(operand);
-        }
-        return ret;
-    }
-
-    @Specialization(guards = {"!preserveNames", "!preserveDimensions"})
-    protected RDoubleVector doComplexVector(RComplexVector operand) {
-        double[] ddata = dataFromComplex(operand);
-        RDoubleVector ret = RDataFactory.createDoubleVector(ddata, naCheck.neverSeenNA());
-        if (isAttrPreservation()) {
-            ret.copyRegAttributesFrom(operand);
-        }
-        return ret;
-    }
-
-    @Specialization(guards = {"!preserveNames", "preserveDimensions"})
-    protected RDoubleVector doRawVectorDims(RRawVector vector) {
-        double[] ddata = dataFromRaw(vector);
-        RDoubleVector ret = RDataFactory.createDoubleVector(ddata, naCheck.neverSeenNA(), vector.getDimensions());
-        if (isAttrPreservation()) {
-            ret.copyRegAttributesFrom(vector);
-        }
-        return ret;
-    }
-
-    @Specialization(guards = {"preserveNames", "!preserveDimensions"})
-    protected RDoubleVector doRawVectorNames(RRawVector vector) {
-        double[] ddata = dataFromRaw(vector);
-        RDoubleVector ret = RDataFactory.createDoubleVector(ddata, naCheck.neverSeenNA(), vector.getNames());
-        if (isAttrPreservation()) {
-            ret.copyRegAttributesFrom(vector);
-        }
-        return ret;
-    }
-
-    @Specialization(guards = {"preserveNames", "preserveDimensions"})
-    protected RDoubleVector doRawVectorDimsNames(RRawVector vector) {
-        double[] ddata = dataFromRaw(vector);
-        RDoubleVector ret = RDataFactory.createDoubleVector(ddata, naCheck.neverSeenNA(), vector.getDimensions(), vector.getNames());
-        if (isAttrPreservation()) {
-            ret.copyRegAttributesFrom(vector);
-        }
-        return ret;
-    }
-
-    @Specialization(guards = {"!preserveNames", "!preserveDimensions"})
-    protected RDoubleVector doRawVector(RRawVector vector) {
-        double[] ddata = dataFromRaw(vector);
-        RDoubleVector ret = RDataFactory.createDoubleVector(ddata, naCheck.neverSeenNA());
-        if (isAttrPreservation()) {
-            ret.copyRegAttributesFrom(vector);
-        }
-        return ret;
+    protected RDoubleVector doRawVector(RRawVector operand) {
+        return createResultVector(operand, index -> RRuntime.raw2double(operand.getDataAt(index)));
     }
 
     @Specialization
@@ -353,10 +205,10 @@ public abstract class CastDoubleNode extends CastNode {
                     } else if (doubleVector.getLength() == 0) {
                         result[i] = RRuntime.DOUBLE_NA;
                     } else {
-                        throw cannotCoerceListError();
+                        throw throwCannotCoerceListError("numeric");
                     }
                 } else {
-                    throw cannotCoerceListError();
+                    throw throwCannotCoerceListError("numeric");
                 }
             }
         }
@@ -367,36 +219,9 @@ public abstract class CastDoubleNode extends CastNode {
         return ret;
     }
 
-    private RError cannotCoerceListError() {
-        throw RError.error(this.getSourceSection(), RError.Message.LIST_COERCION, "numeric");
-    }
-
     @Fallback
     @TruffleBoundary
     public double doOther(Object operand) {
         throw new ConversionFailedException(operand.getClass().getName());
     }
-
-    private RDoubleVector performAbstractIntVector(RAbstractIntVector operand) {
-        naCheck.enable(operand);
-        double[] ddata = new double[operand.getLength()];
-        for (int i = 0; i < operand.getLength(); i++) {
-            int value = operand.getDataAt(i);
-            ddata[i] = naCheck.convertIntToDouble(value);
-        }
-        RDoubleVector ret;
-        if (preserveDimensions() && preserveNames()) {
-            ret = RDataFactory.createDoubleVector(ddata, naCheck.neverSeenNA(), operand.getDimensions(), operand.getNames());
-        } else if (preserveDimensions()) {
-            ret = RDataFactory.createDoubleVector(ddata, naCheck.neverSeenNA(), operand.getDimensions());
-        } else if (preserveNames()) {
-            ret = RDataFactory.createDoubleVector(ddata, naCheck.neverSeenNA(), operand.getNames());
-        } else {
-            ret = RDataFactory.createDoubleVector(ddata, naCheck.neverSeenNA());
-        }
-        if (isAttrPreservation()) {
-            ret.copyRegAttributesFrom(operand);
-        }
-        return ret;
-    }
 }
diff --git a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/unary/CastIntegerNode.java b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/unary/CastIntegerNode.java
index 998644035246af4fc4f2002ea1b8bcf71d97e135..3cdc934cb82a28e8b22095d2a00984fa0eb1464c 100644
--- a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/unary/CastIntegerNode.java
+++ b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/unary/CastIntegerNode.java
@@ -23,17 +23,19 @@
 package com.oracle.truffle.r.nodes.unary;
 
 import com.oracle.truffle.api.*;
-import com.oracle.truffle.api.CompilerDirectives.*;
+import com.oracle.truffle.api.CompilerDirectives.TruffleBoundary;
 import com.oracle.truffle.api.dsl.*;
 import com.oracle.truffle.api.frame.*;
-import com.oracle.truffle.r.nodes.unary.ConvertNode.ConversionFailedException;
+import com.oracle.truffle.api.utilities.*;
 import com.oracle.truffle.r.runtime.*;
 import com.oracle.truffle.r.runtime.data.*;
+import com.oracle.truffle.r.runtime.data.model.*;
 import com.oracle.truffle.r.runtime.ops.na.*;
 
 public abstract class CastIntegerNode extends CastNode {
 
-    private final NACheck check = NACheck.create();
+    private final NACheck naCheck = NACheck.create();
+    private final BranchProfile warningBranch = BranchProfile.create();
 
     public abstract Object executeInt(VirtualFrame frame, int o);
 
@@ -48,7 +50,7 @@ public abstract class CastIntegerNode extends CastNode {
     private Object castIntegerRecursive(VirtualFrame frame, Object o) {
         if (recursiveCastInteger == null) {
             CompilerDirectives.transferToInterpreterAndInvalidate();
-            recursiveCastInteger = insert(CastIntegerNodeFactory.create(null, isNamesPreservation(), isDimensionsPreservation(), isAttrPreservation()));
+            recursiveCastInteger = insert(CastIntegerNodeFactory.create(null, isPreserveNames(), isDimensionsPreservation(), isAttrPreservation()));
         }
         return recursiveCastInteger.executeInt(frame, o);
     }
@@ -70,8 +72,8 @@ public abstract class CastIntegerNode extends CastNode {
 
     @Specialization
     protected int doDouble(double operand) {
-        check.enable(operand);
-        return check.convertDoubleToInt(operand);
+        naCheck.enable(operand);
+        return naCheck.convertDoubleToInt(operand);
     }
 
     @Specialization
@@ -86,15 +88,16 @@ public abstract class CastIntegerNode extends CastNode {
 
     @Specialization
     protected RIntSequence doDoubleSequence(RDoubleSequence operand) {
-        check.enable(operand);
-        return RDataFactory.createIntSequence(check.convertDoubleToInt(operand.getStart()), check.convertDoubleToInt(operand.getStride()), operand.getLength());
+        naCheck.enable(operand);
+        return RDataFactory.createIntSequence(naCheck.convertDoubleToInt(operand.getStart()), naCheck.convertDoubleToInt(operand.getStride()), operand.getLength());
     }
 
     @Specialization
     protected int doComplex(RComplex operand) {
-        check.enable(operand);
-        int result = check.convertComplexToInt(operand);
+        naCheck.enable(operand);
+        int result = naCheck.convertComplexToInt(operand);
         if (operand.getImaginaryPart() != 0.0) {
+            warningBranch.enter();
             RError.warning(RError.Message.IMAGINARY_PARTS_DISCARDED_IN_COERCION);
         }
         return result;
@@ -102,9 +105,10 @@ public abstract class CastIntegerNode extends CastNode {
 
     @Specialization
     protected int doCharacter(String operand) {
-        check.enable(operand);
-        int result = check.convertStringToInt(operand);
+        naCheck.enable(operand);
+        int result = naCheck.convertStringToInt(operand);
         if (isNA(result)) {
+            warningBranch.enter();
             RError.warning(RError.Message.NA_INTRODUCED_COERCION);
         }
         return result;
@@ -112,8 +116,8 @@ public abstract class CastIntegerNode extends CastNode {
 
     @Specialization
     protected int doBoolean(byte operand) {
-        check.enable(operand);
-        return check.convertLogicalToInt(operand);
+        naCheck.enable(operand);
+        return naCheck.convertLogicalToInt(operand);
     }
 
     @Specialization
@@ -121,262 +125,81 @@ public abstract class CastIntegerNode extends CastNode {
         return RRuntime.raw2int(operand);
     }
 
-    private int[] dataFromComplex(RComplexVector operand) {
-        check.enable(operand);
+    private RIntVector createResultVector(RAbstractVector operand, int[] idata) {
+        RIntVector ret = RDataFactory.createIntVector(idata, naCheck.neverSeenNA(), isPreserveDimensions() ? operand.getDimensions() : null, isPreserveNames() ? operand.getNames() : null);
+        if (isAttrPreservation()) {
+            ret.copyRegAttributesFrom(operand);
+        }
+        return ret;
+    }
+
+    @FunctionalInterface
+    private interface IntToIntFunction {
+        int apply(int value);
+    }
+
+    private RIntVector createResultVector(RAbstractVector operand, IntToIntFunction elementFunction) {
+        naCheck.enable(operand);
+        int[] idata = new int[operand.getLength()];
+        for (int i = 0; i < operand.getLength(); i++) {
+            idata[i] = elementFunction.apply(i);
+        }
+        return createResultVector(operand, idata);
+    }
+
+    @Specialization
+    protected RIntVector doComplexVector(RComplexVector operand) {
+        naCheck.enable(operand);
         int length = operand.getLength();
         int[] idata = new int[length];
         boolean warning = false;
         for (int i = 0; i < length; i++) {
             RComplex data = operand.getDataAt(i);
-            idata[i] = check.convertComplexToInt(data, false);
+            idata[i] = naCheck.convertComplexToInt(data, false);
             if (data.getImaginaryPart() != 0.0) {
                 warning = true;
             }
         }
         if (warning) {
+            warningBranch.enter();
             RError.warning(RError.Message.IMAGINARY_PARTS_DISCARDED_IN_COERCION);
         }
-        return idata;
+        return createResultVector(operand, idata);
     }
 
-    private int[] dataFromString(RStringVector operand) {
-        check.enable(operand);
+    @Specialization
+    protected RIntVector doStringVector(RStringVector operand) {
+        naCheck.enable(operand);
         int[] idata = new int[operand.getLength()];
         boolean warning = false;
         for (int i = 0; i < operand.getLength(); i++) {
             String value = operand.getDataAt(i);
-            idata[i] = check.convertStringToInt(value);
+            idata[i] = naCheck.convertStringToInt(value);
             if (RRuntime.isNA(idata[i])) {
                 warning = true;
             }
         }
         if (warning) {
+            warningBranch.enter();
             RError.warning(RError.Message.NA_INTRODUCED_COERCION);
         }
-        return idata;
-    }
-
-    private int[] dataFromLogical(RLogicalVector operand) {
-        check.enable(operand);
-        int[] idata = new int[operand.getLength()];
-        for (int i = 0; i < operand.getLength(); i++) {
-            byte value = operand.getDataAt(i);
-            idata[i] = check.convertLogicalToInt(value);
-        }
-        return idata;
-    }
-
-    private static int[] dataFromRaw(RRawVector operand) {
-        int[] idata = new int[operand.getLength()];
-        for (int i = 0; i < operand.getLength(); i++) {
-            RRaw value = operand.getDataAt(i);
-            idata[i] = RRuntime.raw2int(value);
-        }
-        return idata;
-    }
-
-    @Specialization(guards = {"!preserveNames", "preserveDimensions"})
-    protected RIntVector doComplexVectorDims(RComplexVector vector) {
-        int[] result = dataFromComplex(vector);
-        RIntVector ret = RDataFactory.createIntVector(result, check.neverSeenNA(), vector.getDimensions());
-        if (isAttrPreservation()) {
-            ret.copyRegAttributesFrom(vector);
-        }
-        return ret;
-    }
-
-    @Specialization(guards = {"preserveNames", "!preserveDimensions"})
-    protected RIntVector doComplexVectorNames(RComplexVector vector) {
-        int[] result = dataFromComplex(vector);
-        RIntVector ret = RDataFactory.createIntVector(result, check.neverSeenNA(), vector.getNames());
-        if (isAttrPreservation()) {
-            ret.copyRegAttributesFrom(vector);
-        }
-        return ret;
-    }
-
-    @Specialization(guards = {"preserveNames", "preserveDimensions"})
-    protected RIntVector doComplexVectorDimsNames(RComplexVector vector) {
-        int[] result = dataFromComplex(vector);
-        RIntVector ret = RDataFactory.createIntVector(result, check.neverSeenNA(), vector.getDimensions(), vector.getNames());
-        if (isAttrPreservation()) {
-            ret.copyRegAttributesFrom(vector);
-        }
-        return ret;
-    }
-
-    @Specialization(guards = {"!preserveNames", "!preserveDimensions"})
-    protected RIntVector doComplexVector(RComplexVector vector) {
-        int[] result = dataFromComplex(vector);
-        RIntVector ret = RDataFactory.createIntVector(result, check.neverSeenNA());
-        if (isAttrPreservation()) {
-            ret.copyRegAttributesFrom(vector);
-        }
-        return ret;
-    }
-
-    @Specialization(guards = {"!preserveNames", "preserveDimensions"})
-    protected RIntVector doStringVectorDims(RStringVector vector) {
-        int[] result = dataFromString(vector);
-        RIntVector ret = RDataFactory.createIntVector(result, check.neverSeenNA(), vector.getDimensions());
-        if (isAttrPreservation()) {
-            ret.copyRegAttributesFrom(vector);
-        }
-        return ret;
-    }
-
-    @Specialization(guards = {"preserveNames", "!preserveDimensions"})
-    protected RIntVector doStringVectorNames(RStringVector vector) {
-        int[] result = dataFromString(vector);
-        RIntVector ret = RDataFactory.createIntVector(result, check.neverSeenNA(), vector.getNames());
-        if (isAttrPreservation()) {
-            ret.copyRegAttributesFrom(vector);
-        }
-        return ret;
-    }
-
-    @Specialization(guards = {"preserveNames", "preserveDimensions"})
-    protected RIntVector doStringVectorDimsNames(RStringVector vector) {
-        int[] result = dataFromString(vector);
-        RIntVector ret = RDataFactory.createIntVector(result, check.neverSeenNA(), vector.getDimensions(), vector.getNames());
-        if (isAttrPreservation()) {
-            ret.copyRegAttributesFrom(vector);
-        }
-        return ret;
-    }
-
-    @Specialization(guards = {"!preserveNames", "!preserveDimensions"})
-    protected RIntVector doStringVector(RStringVector vector) {
-        int[] result = dataFromString(vector);
-        RIntVector ret = RDataFactory.createIntVector(result, check.neverSeenNA());
-        if (isAttrPreservation()) {
-            ret.copyRegAttributesFrom(vector);
-        }
-        return ret;
-    }
-
-    @Specialization(guards = {"!preserveNames", "preserveDimensions"})
-    protected RIntVector doLogicalVectorDims(RLogicalVector vector) {
-        int[] result = dataFromLogical(vector);
-        RIntVector ret = RDataFactory.createIntVector(result, check.neverSeenNA(), vector.getDimensions());
-        if (isAttrPreservation()) {
-            ret.copyRegAttributesFrom(vector);
-        }
-        return ret;
-    }
-
-    @Specialization(guards = {"preserveNames", "!preserveDimensions"})
-    protected RIntVector doLogicalVectorNames(RLogicalVector vector) {
-        int[] result = dataFromLogical(vector);
-        RIntVector ret = RDataFactory.createIntVector(result, check.neverSeenNA(), vector.getNames());
-        if (isAttrPreservation()) {
-            ret.copyRegAttributesFrom(vector);
-        }
-        return ret;
-    }
-
-    @Specialization(guards = {"preserveNames", "preserveDimensions"})
-    protected RIntVector doLogicalVectorDimsNames(RLogicalVector vector) {
-        int[] result = dataFromLogical(vector);
-        RIntVector ret = RDataFactory.createIntVector(result, check.neverSeenNA(), vector.getDimensions(), vector.getNames());
-        if (isAttrPreservation()) {
-            ret.copyRegAttributesFrom(vector);
-        }
-        return ret;
-    }
-
-    @Specialization(guards = {"!preserveNames", "!preserveDimensions"})
-    public RIntVector doLogicalVector(RLogicalVector vector) {
-        int[] result = dataFromLogical(vector);
-        RIntVector ret = RDataFactory.createIntVector(result, check.neverSeenNA());
-        if (isAttrPreservation()) {
-            ret.copyRegAttributesFrom(vector);
-        }
-        return ret;
-    }
-
-    @Specialization(guards = {"!preserveNames", "preserveDimensions"})
-    protected RIntVector doDoubleVectorDims(RDoubleVector vector) {
-        check.enable(vector);
-        int[] result = check.convertDoubleVectorToIntData(vector);
-        RIntVector ret = RDataFactory.createIntVector(result, check.neverSeenNA(), vector.getDimensions());
-        if (isAttrPreservation()) {
-            ret.copyRegAttributesFrom(vector);
-        }
-        return ret;
-    }
-
-    @Specialization(guards = {"preserveNames", "!preserveDimensions"})
-    protected RIntVector doDoubleVectorNames(RDoubleVector vector) {
-        check.enable(vector);
-        int[] result = check.convertDoubleVectorToIntData(vector);
-        RIntVector ret = RDataFactory.createIntVector(result, check.neverSeenNA(), vector.getNames());
-        if (isAttrPreservation()) {
-            ret.copyRegAttributesFrom(vector);
-        }
-        return ret;
-    }
-
-    @Specialization(guards = {"preserveNames", "preserveDimensions"})
-    protected RIntVector doDoubleVectorDimsNames(RDoubleVector vector) {
-        check.enable(vector);
-        int[] result = check.convertDoubleVectorToIntData(vector);
-        RIntVector ret = RDataFactory.createIntVector(result, check.neverSeenNA(), vector.getDimensions(), vector.getNames());
-        if (isAttrPreservation()) {
-            ret.copyRegAttributesFrom(vector);
-        }
-        return ret;
-    }
-
-    @Specialization(guards = {"!preserveNames", "!preserveDimensions"})
-    protected RIntVector doDoubleVector(RDoubleVector vector) {
-        check.enable(vector);
-        int[] result = check.convertDoubleVectorToIntData(vector);
-        RIntVector ret = RDataFactory.createIntVector(result, check.neverSeenNA());
-        if (isAttrPreservation()) {
-            ret.copyRegAttributesFrom(vector);
-        }
-        return ret;
-    }
-
-    @Specialization(guards = {"!preserveNames", "preserveDimensions"})
-    protected RIntVector doRawVectorDims(RRawVector vector) {
-        int[] result = dataFromRaw(vector);
-        RIntVector ret = RDataFactory.createIntVector(result, check.neverSeenNA(), vector.getDimensions());
-        if (isAttrPreservation()) {
-            ret.copyRegAttributesFrom(vector);
-        }
-        return ret;
+        return createResultVector(operand, idata);
     }
 
-    @Specialization(guards = {"preserveNames", "!preserveDimensions"})
-    protected RIntVector doRawVectorNames(RRawVector vector) {
-        int[] result = dataFromRaw(vector);
-        RIntVector ret = RDataFactory.createIntVector(result, check.neverSeenNA(), vector.getNames());
-        if (isAttrPreservation()) {
-            ret.copyRegAttributesFrom(vector);
-        }
-        return ret;
+    @Specialization
+    public RIntVector doLogicalVector(RLogicalVector operand) {
+        return createResultVector(operand, index -> naCheck.convertLogicalToInt(operand.getDataAt(index)));
     }
 
-    @Specialization(guards = {"preserveNames", "preserveDimensions"})
-    protected RIntVector doRawVectorDimsNames(RRawVector vector) {
-        int[] result = dataFromRaw(vector);
-        RIntVector ret = RDataFactory.createIntVector(result, check.neverSeenNA(), vector.getDimensions(), vector.getNames());
-        if (isAttrPreservation()) {
-            ret.copyRegAttributesFrom(vector);
-        }
-        return ret;
+    @Specialization
+    protected RIntVector doDoubleVector(RDoubleVector operand) {
+        naCheck.enable(operand);
+        return createResultVector(operand, naCheck.convertDoubleVectorToIntData(operand));
     }
 
-    @Specialization(guards = {"!preserveNames", "!preserveDimensions"})
-    protected RIntVector doRawVector(RRawVector vector) {
-        int[] result = dataFromRaw(vector);
-        RIntVector ret = RDataFactory.createIntVector(result, check.neverSeenNA());
-        if (isAttrPreservation()) {
-            ret.copyRegAttributesFrom(vector);
-        }
-        return ret;
+    @Specialization
+    protected RIntVector doRawVector(RRawVector operand) {
+        return createResultVector(operand, index -> RRuntime.raw2int(operand.getDataAt(index)));
     }
 
     @Specialization
@@ -398,14 +221,14 @@ public abstract class CastIntegerNode extends CastNode {
                     } else if (intVector.getLength() == 0) {
                         result[i] = RRuntime.INT_NA;
                     } else {
-                        throw cannotCoerceListError();
+                        throw throwCannotCoerceListError("integer");
                     }
                 } else {
-                    throw cannotCoerceListError();
+                    throw throwCannotCoerceListError("integer");
                 }
             }
         }
-        RIntVector ret = RDataFactory.createIntVector(result, check.neverSeenNA());
+        RIntVector ret = RDataFactory.createIntVector(result, naCheck.neverSeenNA());
         if (isAttrPreservation()) {
             ret.copyRegAttributesFrom(list);
         }
@@ -417,14 +240,9 @@ public abstract class CastIntegerNode extends CastNode {
         return factor.getVector();
     }
 
-    private RError cannotCoerceListError() {
-        throw RError.error(this.getSourceSection(), RError.Message.LIST_COERCION, "integer");
-    }
-
     @Fallback
     @TruffleBoundary
     public int doOther(Object operand) {
         throw new ConversionFailedException(operand.getClass().getName());
     }
-
 }
diff --git a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/unary/CastListNode.java b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/unary/CastListNode.java
index 84c5863e47bb5307e7532bfe9896f0bf915a6c55..1c0133786222e3e28da4182a5bb92b80e7237999 100644
--- a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/unary/CastListNode.java
+++ b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/unary/CastListNode.java
@@ -44,8 +44,7 @@ public abstract class CastListNode extends CastNode {
     }
 
     @Specialization
-    @SuppressWarnings("unused")
-    protected RList doNull(RNull operand) {
+    protected RList doNull(@SuppressWarnings("unused") RNull operand) {
         return RDataFactory.createList();
     }
 
@@ -65,16 +64,7 @@ public abstract class CastListNode extends CastNode {
         for (int i = 0; i < data.length; ++i) {
             data[i] = operand.getDataAtAsObject(i);
         }
-        RList ret;
-        if (preserveDimensions() && preserveNames()) {
-            ret = RDataFactory.createList(data, operand.getDimensions(), operand.getNames());
-        } else if (preserveDimensions()) {
-            ret = RDataFactory.createList(data, operand.getDimensions());
-        } else if (preserveNames()) {
-            ret = RDataFactory.createList(data, operand.getNames());
-        } else {
-            ret = RDataFactory.createList(data);
-        }
+        RList ret = RDataFactory.createList(data, isPreserveDimensions() ? operand.getDimensions() : null, isPreserveNames() ? operand.getNames() : null);
         if (isAttrPreservation()) {
             ret.copyRegAttributesFrom(operand);
         }
@@ -95,5 +85,4 @@ public abstract class CastListNode extends CastNode {
     protected RList doDataFrame(VirtualFrame frame, RDataFrame operand) {
         return castList(frame, operand.getVector());
     }
-
 }
diff --git a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/unary/CastLogicalNode.java b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/unary/CastLogicalNode.java
index 6cad5ade807b7b9ee86d99420740c7bb56762308..0a6857b8a718338e1c25ff723bde49040e66f110 100644
--- a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/unary/CastLogicalNode.java
+++ b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/unary/CastLogicalNode.java
@@ -26,7 +26,6 @@ import com.oracle.truffle.api.*;
 import com.oracle.truffle.api.CompilerDirectives.TruffleBoundary;
 import com.oracle.truffle.api.dsl.*;
 import com.oracle.truffle.api.frame.*;
-import com.oracle.truffle.r.nodes.unary.ConvertNode.*;
 import com.oracle.truffle.r.runtime.*;
 import com.oracle.truffle.r.runtime.data.*;
 import com.oracle.truffle.r.runtime.data.model.*;
@@ -45,7 +44,7 @@ public abstract class CastLogicalNode extends CastNode {
     private Object castLogicalRecursive(VirtualFrame frame, Object o) {
         if (recursiveCastLogical == null) {
             CompilerDirectives.transferToInterpreterAndInvalidate();
-            recursiveCastLogical = insert(CastLogicalNodeFactory.create(null, isNamesPreservation(), isDimensionsPreservation(), isAttrPreservation()));
+            recursiveCastLogical = insert(CastLogicalNodeFactory.create(null, isPreserveNames(), isDimensionsPreservation(), isAttrPreservation()));
         }
         return recursiveCastLogical.executeLogical(frame, o);
     }
@@ -89,33 +88,22 @@ public abstract class CastLogicalNode extends CastNode {
         return RRuntime.raw2logical(operand);
     }
 
-    private byte[] dataFromString(RStringVector operand) {
-        naCheck.enable(operand);
-        byte[] ldata = new byte[operand.getLength()];
-        for (int i = 0; i < operand.getLength(); i++) {
-            String value = operand.getDataAt(i);
-            ldata[i] = naCheck.convertStringToLogical(value);
-        }
-        return ldata;
+    @FunctionalInterface
+    private interface IntToByteFunction {
+        byte apply(int value);
     }
 
-    private byte[] dataFromComplex(RComplexVector operand) {
+    private RLogicalVector createResultVector(RAbstractVector operand, IntToByteFunction elementFunction) {
         naCheck.enable(operand);
-        byte[] ldata = new byte[operand.getLength()];
+        byte[] bdata = new byte[operand.getLength()];
         for (int i = 0; i < operand.getLength(); i++) {
-            RComplex value = operand.getDataAt(i);
-            ldata[i] = naCheck.convertComplexToLogical(value);
+            bdata[i] = elementFunction.apply(i);
         }
-        return ldata;
-    }
-
-    private static byte[] dataFromRaw(RRawVector operand) {
-        byte[] ldata = new byte[operand.getLength()];
-        for (int i = 0; i < operand.getLength(); i++) {
-            RRaw value = operand.getDataAt(i);
-            ldata[i] = RRuntime.raw2logical(value);
+        RLogicalVector ret = RDataFactory.createLogicalVector(bdata, naCheck.neverSeenNA(), isPreserveDimensions() ? operand.getDimensions() : null, isPreserveNames() ? operand.getNames() : null);
+        if (isAttrPreservation()) {
+            ret.copyRegAttributesFrom(operand);
         }
-        return ldata;
+        return ret;
     }
 
     @Specialization
@@ -124,143 +112,28 @@ public abstract class CastLogicalNode extends CastNode {
     }
 
     @Specialization
-    protected RLogicalVector doIntVector(RIntVector operand) {
-        return performAbstractIntVector(operand);
-    }
-
-    @Specialization
-    protected RLogicalVector doIntSequence(RIntSequence operand) {
-        return performAbstractIntVector(operand);
+    protected RLogicalVector doIntVector(RAbstractIntVector operand) {
+        return createResultVector(operand, index -> naCheck.convertIntToLogical(operand.getDataAt(index)));
     }
 
     @Specialization
-    protected RLogicalVector doDoubleVector(RDoubleVector operand) {
-        return performAbstractDoubleVector(operand);
+    protected RLogicalVector doDoubleVector(RAbstractDoubleVector operand) {
+        return createResultVector(operand, index -> naCheck.convertDoubleToLogical(operand.getDataAt(index)));
     }
 
     @Specialization
-    protected RLogicalVector doDoubleSequence(RDoubleSequence operand) {
-        return performAbstractDoubleVector(operand);
-    }
-
-    @Specialization(guards = {"!preserveNames", "preserveDimensions"})
-    protected RLogicalVector doStringVectorDims(RStringVector operand) {
-        byte[] ldata = dataFromString(operand);
-        RLogicalVector ret = RDataFactory.createLogicalVector(ldata, naCheck.neverSeenNA(), operand.getDimensions());
-        if (isAttrPreservation()) {
-            ret.copyRegAttributesFrom(operand);
-        }
-        return ret;
-    }
-
-    @Specialization(guards = {"preserveNames", "!preserveDimensions"})
-    protected RLogicalVector doStringVectorNames(RStringVector operand) {
-        byte[] ldata = dataFromString(operand);
-        RLogicalVector ret = RDataFactory.createLogicalVector(ldata, naCheck.neverSeenNA(), operand.getNames());
-        if (isAttrPreservation()) {
-            ret.copyRegAttributesFrom(operand);
-        }
-        return ret;
-    }
-
-    @Specialization(guards = {"preserveNames", "preserveDimensions"})
-    protected RLogicalVector doStringVectorDimsNames(RStringVector operand) {
-        byte[] ldata = dataFromString(operand);
-        RLogicalVector ret = RDataFactory.createLogicalVector(ldata, naCheck.neverSeenNA(), operand.getDimensions(), operand.getNames());
-        if (isAttrPreservation()) {
-            ret.copyRegAttributesFrom(operand);
-        }
-        return ret;
-    }
-
-    @Specialization(guards = {"!preserveNames", "!preserveDimensions"})
     protected RLogicalVector doStringVector(RStringVector operand) {
-        byte[] ldata = dataFromString(operand);
-        RLogicalVector ret = RDataFactory.createLogicalVector(ldata, naCheck.neverSeenNA());
-        if (isAttrPreservation()) {
-            ret.copyRegAttributesFrom(operand);
-        }
-        return ret;
-    }
-
-    @Specialization(guards = {"!preserveNames", "preserveDimensions"})
-    protected RLogicalVector doComplexVectorDims(RComplexVector operand) {
-        byte[] ldata = dataFromComplex(operand);
-        RLogicalVector ret = RDataFactory.createLogicalVector(ldata, naCheck.neverSeenNA(), operand.getDimensions());
-        if (isAttrPreservation()) {
-            ret.copyRegAttributesFrom(operand);
-        }
-        return ret;
-    }
-
-    @Specialization(guards = {"preserveNames", "!preserveDimensions"})
-    protected RLogicalVector doComplexVectorNames(RComplexVector operand) {
-        byte[] ldata = dataFromComplex(operand);
-        RLogicalVector ret = RDataFactory.createLogicalVector(ldata, naCheck.neverSeenNA(), operand.getNames());
-        if (isAttrPreservation()) {
-            ret.copyRegAttributesFrom(operand);
-        }
-        return ret;
-    }
-
-    @Specialization(guards = {"preserveNames", "preserveDimensions"})
-    protected RLogicalVector doComplexVectorDimsNames(RComplexVector operand) {
-        byte[] ldata = dataFromComplex(operand);
-        RLogicalVector ret = RDataFactory.createLogicalVector(ldata, naCheck.neverSeenNA(), operand.getDimensions(), operand.getNames());
-        if (isAttrPreservation()) {
-            ret.copyRegAttributesFrom(operand);
-        }
-        return ret;
+        return createResultVector(operand, index -> naCheck.convertStringToLogical(operand.getDataAt(index)));
     }
 
-    @Specialization(guards = {"!preserveNames", "!preserveDimensions"})
+    @Specialization
     protected RLogicalVector doComplexVector(RComplexVector operand) {
-        byte[] ldata = dataFromComplex(operand);
-        RLogicalVector ret = RDataFactory.createLogicalVector(ldata, naCheck.neverSeenNA());
-        if (isAttrPreservation()) {
-            ret.copyRegAttributesFrom(operand);
-        }
-        return ret;
+        return createResultVector(operand, index -> naCheck.convertComplexToLogical(operand.getDataAt(index)));
     }
 
-    @Specialization(guards = {"!preserveNames", "preserveDimensions"})
+    @Specialization
     protected RLogicalVector doRawVectorDims(RRawVector operand) {
-        byte[] ldata = dataFromRaw(operand);
-        RLogicalVector ret = RDataFactory.createLogicalVector(ldata, RDataFactory.COMPLETE_VECTOR, operand.getDimensions());
-        if (isAttrPreservation()) {
-            ret.copyRegAttributesFrom(operand);
-        }
-        return ret;
-    }
-
-    @Specialization(guards = {"preserveNames", "!preserveDimensions"})
-    protected RLogicalVector doRawVectorNames(RRawVector operand) {
-        byte[] ldata = dataFromRaw(operand);
-        RLogicalVector ret = RDataFactory.createLogicalVector(ldata, RDataFactory.COMPLETE_VECTOR, operand.getNames());
-        if (isAttrPreservation()) {
-            ret.copyRegAttributesFrom(operand);
-        }
-        return ret;
-    }
-
-    @Specialization(guards = {"preserveNames", "preserveDimensions"})
-    protected RLogicalVector doRawVectorDimsNames(RRawVector operand) {
-        byte[] ldata = dataFromRaw(operand);
-        RLogicalVector ret = RDataFactory.createLogicalVector(ldata, RDataFactory.COMPLETE_VECTOR, operand.getDimensions(), operand.getNames());
-        if (isAttrPreservation()) {
-            ret.copyRegAttributesFrom(operand);
-        }
-        return ret;
-    }
-
-    @Specialization(guards = {"!preserveNames", "!preserveDimensions"})
-    protected RLogicalVector doRawVector(RRawVector operand) {
-        byte[] ldata = dataFromRaw(operand);
-        RLogicalVector ret = RDataFactory.createLogicalVector(ldata, RDataFactory.COMPLETE_VECTOR);
-        if (isAttrPreservation()) {
-            ret.copyRegAttributesFrom(operand);
-        }
-        return ret;
+        return createResultVector(operand, index -> RRuntime.raw2logical(operand.getDataAt(index)));
     }
 
     @Specialization
@@ -282,10 +155,10 @@ public abstract class CastLogicalNode extends CastNode {
                     } else if (logicalVector.getLength() == 0) {
                         result[i] = RRuntime.LOGICAL_NA;
                     } else {
-                        throw cannotCoerceListError();
+                        throw throwCannotCoerceListError("logical");
                     }
                 } else {
-                    throw cannotCoerceListError();
+                    throw throwCannotCoerceListError("logical");
                 }
             }
         }
@@ -296,10 +169,6 @@ public abstract class CastLogicalNode extends CastNode {
         return ret;
     }
 
-    private RError cannotCoerceListError() {
-        throw RError.error(this.getSourceSection(), RError.Message.LIST_COERCION, "logical");
-    }
-
     @Specialization
     protected RArgsValuesAndNames doArgsValueAndNames(RArgsValuesAndNames values) {
         return values;
@@ -315,50 +184,4 @@ public abstract class CastLogicalNode extends CastNode {
     public int doOther(Object operand) {
         throw new ConversionFailedException(operand.getClass().getName());
     }
-
-    private RLogicalVector performAbstractIntVector(RAbstractIntVector operand) {
-        naCheck.enable(operand);
-        byte[] ddata = new byte[operand.getLength()];
-        for (int i = 0; i < operand.getLength(); i++) {
-            int value = operand.getDataAt(i);
-            ddata[i] = naCheck.convertIntToLogical(value);
-        }
-        RLogicalVector ret;
-        if (preserveDimensions() && preserveNames()) {
-            ret = RDataFactory.createLogicalVector(ddata, naCheck.neverSeenNA(), operand.getDimensions(), operand.getNames());
-        } else if (preserveDimensions()) {
-            ret = RDataFactory.createLogicalVector(ddata, naCheck.neverSeenNA(), operand.getDimensions());
-        } else if (preserveNames()) {
-            ret = RDataFactory.createLogicalVector(ddata, naCheck.neverSeenNA(), operand.getNames());
-        } else {
-            ret = RDataFactory.createLogicalVector(ddata, naCheck.neverSeenNA());
-        }
-        if (isAttrPreservation()) {
-            ret.copyRegAttributesFrom(operand);
-        }
-        return ret;
-    }
-
-    private RLogicalVector performAbstractDoubleVector(RAbstractDoubleVector operand) {
-        naCheck.enable(operand);
-        byte[] ddata = new byte[operand.getLength()];
-        for (int i = 0; i < operand.getLength(); i++) {
-            double value = operand.getDataAt(i);
-            ddata[i] = naCheck.convertDoubleToLogical(value);
-        }
-        RLogicalVector ret;
-        if (preserveDimensions() && preserveNames()) {
-            ret = RDataFactory.createLogicalVector(ddata, naCheck.neverSeenNA(), operand.getDimensions(), operand.getNames());
-        } else if (preserveDimensions()) {
-            ret = RDataFactory.createLogicalVector(ddata, naCheck.neverSeenNA(), operand.getDimensions());
-        } else if (preserveNames()) {
-            ret = RDataFactory.createLogicalVector(ddata, naCheck.neverSeenNA(), operand.getNames());
-        } else {
-            ret = RDataFactory.createLogicalVector(ddata, naCheck.neverSeenNA());
-        }
-        if (isAttrPreservation()) {
-            ret.copyRegAttributesFrom(operand);
-        }
-        return ret;
-    }
 }
diff --git a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/unary/CastNode.java b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/unary/CastNode.java
index 25ebaf0870b74a5aec7bf80d7443719dcd2aeded..b06e0110514929340b5c5058744a7d27eb5ca39c 100644
--- a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/unary/CastNode.java
+++ b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/unary/CastNode.java
@@ -24,24 +24,28 @@ package com.oracle.truffle.r.nodes.unary;
 
 import com.oracle.truffle.api.dsl.*;
 import com.oracle.truffle.api.frame.*;
+import com.oracle.truffle.api.utilities.*;
+import com.oracle.truffle.r.runtime.*;
 
-@NodeFields({@NodeField(name = "namesPreservation", type = boolean.class), @NodeField(name = "dimensionsPreservation", type = boolean.class),
-                @NodeField(name = "attrPreservation", type = boolean.class)})
+@NodeFields({@NodeField(name = "preserveNames", type = boolean.class), @NodeField(name = "dimensionsPreservation", type = boolean.class), @NodeField(name = "attrPreservation", type = boolean.class)})
 public abstract class CastNode extends UnaryNode {
 
+    private final BranchProfile listCoercionErrorBranch = BranchProfile.create();
+
     public abstract Object executeCast(VirtualFrame frame, Object value);
 
-    protected abstract boolean isNamesPreservation();
+    protected abstract boolean isPreserveNames();
 
     protected abstract boolean isDimensionsPreservation();
 
     protected abstract boolean isAttrPreservation();
 
-    protected boolean preserveNames() {
-        return isNamesPreservation();
+    protected boolean isPreserveDimensions() {
+        return isDimensionsPreservation();
     }
 
-    protected boolean preserveDimensions() {
-        return isDimensionsPreservation();
+    protected RError throwCannotCoerceListError(String type) {
+        listCoercionErrorBranch.enter();
+        throw RError.error(getSourceSection(), RError.Message.LIST_COERCION, type);
     }
 }
diff --git a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/unary/CastRawNode.java b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/unary/CastRawNode.java
index 1c9473026df1b76f091d55544a41f678b4674f7d..82b85b9192c6a318fe9e7c8902356fac0876ebf8 100644
--- a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/unary/CastRawNode.java
+++ b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/unary/CastRawNode.java
@@ -25,13 +25,15 @@ package com.oracle.truffle.r.nodes.unary;
 import com.oracle.truffle.api.CompilerDirectives.TruffleBoundary;
 import com.oracle.truffle.api.dsl.*;
 import com.oracle.truffle.api.frame.*;
-import com.oracle.truffle.r.nodes.unary.ConvertNode.ConversionFailedException;
+import com.oracle.truffle.api.utilities.*;
 import com.oracle.truffle.r.runtime.*;
 import com.oracle.truffle.r.runtime.data.*;
 import com.oracle.truffle.r.runtime.data.model.*;
 
 public abstract class CastRawNode extends CastNode {
 
+    private final BranchProfile warningBranch = BranchProfile.create();
+
     public abstract Object executeRaw(VirtualFrame frame, int o);
 
     public abstract Object executeRaw(VirtualFrame frame, double o);
@@ -49,6 +51,7 @@ public abstract class CastRawNode extends CastNode {
     protected RRaw doInt(int operand) {
         int intResult = RRuntime.int2rawIntValue(operand);
         if (intResult != operand) {
+            warningBranch.enter();
             RError.warning(RError.Message.OUT_OF_RANGE);
         }
         return RDataFactory.createRaw((byte) intResult);
@@ -58,6 +61,7 @@ public abstract class CastRawNode extends CastNode {
     protected RRaw doDouble(double operand) {
         int intResult = RRuntime.double2rawIntValue(operand);
         if (intResult != (int) operand) {
+            warningBranch.enter();
             RError.warning(RError.Message.OUT_OF_RANGE);
         }
         return RDataFactory.createRaw((byte) intResult);
@@ -67,9 +71,11 @@ public abstract class CastRawNode extends CastNode {
     protected RRaw doComplex(RComplex operand) {
         int intResult = RRuntime.complex2rawIntValue(operand);
         if (operand.getImaginaryPart() != 0) {
+            warningBranch.enter();
             RError.warning(RError.Message.IMAGINARY_PARTS_DISCARDED_IN_COERCION);
         }
         if (intResult != (int) operand.getRealPart()) {
+            warningBranch.enter();
             RError.warning(RError.Message.OUT_OF_RANGE);
         }
         return RDataFactory.createRaw((byte) intResult);
@@ -92,36 +98,42 @@ public abstract class CastRawNode extends CastNode {
         // need to cast to int to catch conversion warnings
         int intVal = RRuntime.string2int(operand);
         if (RRuntime.isNA(intVal)) {
+            warningBranch.enter();
             RError.warning(RError.Message.NA_INTRODUCED_COERCION);
         }
         return doInt(intVal);
     }
 
-    private static byte[] dataFromComplex(RComplexVector operand) {
-        byte[] bdata = new byte[operand.getLength()];
-        boolean imaginaryDiscardedWarning = false;
-        boolean outOfRangeWarning = false;
-        for (int i = 0; i < operand.getLength(); i++) {
-            RComplex complexVal = operand.getDataAt(i);
-            int intRawValue = RRuntime.complex2rawIntValue(complexVal);
-            if (complexVal.getImaginaryPart() != 0.0) {
-                imaginaryDiscardedWarning = true;
-            }
-            if ((int) complexVal.getRealPart() != intRawValue) {
-                outOfRangeWarning = true;
+    private RRawVector createResultVector(RAbstractVector operand, byte[] bdata) {
+        RRawVector ret = RDataFactory.createRawVector(bdata, isPreserveDimensions() ? operand.getDimensions() : null, isPreserveNames() ? operand.getNames() : null);
+        if (isAttrPreservation()) {
+            ret.copyRegAttributesFrom(operand);
+        }
+        return ret;
+    }
+
+    @Specialization
+    protected RRawVector doIntVector(RAbstractIntVector operand) {
+        int length = operand.getLength();
+        byte[] bdata = new byte[length];
+        boolean warning = false;
+        for (int i = 0; i < length; ++i) {
+            int intValue = operand.getDataAt(i);
+            int intRawValue = RRuntime.int2rawIntValue(intValue);
+            if (intRawValue != intValue) {
+                warning = true;
             }
             bdata[i] = (byte) intRawValue;
         }
-        if (imaginaryDiscardedWarning) {
-            RError.warning(RError.Message.IMAGINARY_PARTS_DISCARDED_IN_COERCION);
-        }
-        if (outOfRangeWarning) {
+        if (warning) {
+            warningBranch.enter();
             RError.warning(RError.Message.OUT_OF_RANGE);
         }
-        return bdata;
+        return createResultVector(operand, bdata);
     }
 
-    private static byte[] dataFromLogical(RLogicalVector operand) {
+    @Specialization
+    protected RRawVector doLogicalVector(RLogicalVector operand) {
         byte[] bdata = new byte[operand.getLength()];
         boolean warning = false;
         for (int i = 0; i < operand.getLength(); i++) {
@@ -133,12 +145,14 @@ public abstract class CastRawNode extends CastNode {
             bdata[i] = (byte) intRawValue;
         }
         if (warning) {
+            warningBranch.enter();
             RError.warning(RError.Message.OUT_OF_RANGE);
         }
-        return bdata;
+        return createResultVector(operand, bdata);
     }
 
-    private static byte[] dataFromString(RStringVector operand) {
+    @Specialization
+    protected RRawVector doStringVector(RStringVector operand) {
         byte[] bdata = new byte[operand.getLength()];
         boolean naCoercionWarning = false;
         boolean outOfRangeWarning = false;
@@ -154,152 +168,61 @@ public abstract class CastRawNode extends CastNode {
             bdata[i] = (byte) intRawValue;
         }
         if (naCoercionWarning) {
+            warningBranch.enter();
             RError.warning(RError.Message.NA_INTRODUCED_COERCION);
         }
         if (outOfRangeWarning) {
+            warningBranch.enter();
             RError.warning(RError.Message.OUT_OF_RANGE);
         }
-        return bdata;
+        return createResultVector(operand, bdata);
     }
 
     @Specialization
-    protected RRawVector doIntVector(RIntVector value) {
-        return performAbstractIntVector(value);
-    }
-
-    @Specialization
-    protected RRawVector doIntSequence(RIntSequence value) {
-        return performAbstractIntVector(value);
-    }
-
-    @Specialization(guards = {"!preserveNames", "preserveDimensions"})
-    protected RRawVector doLogicalVectorDims(RLogicalVector operand) {
-        byte[] bdata = dataFromLogical(operand);
-        RRawVector ret = RDataFactory.createRawVector(bdata, operand.getDimensions());
-        if (isAttrPreservation()) {
-            ret.copyRegAttributesFrom(operand);
-        }
-        return ret;
-    }
-
-    @Specialization(guards = {"preserveNames", "!preserveDimensions"})
-    protected RRawVector doLogicalVectorNames(RLogicalVector operand) {
-        byte[] bdata = dataFromLogical(operand);
-        RRawVector ret = RDataFactory.createRawVector(bdata, operand.getNames());
-        if (isAttrPreservation()) {
-            ret.copyRegAttributesFrom(operand);
-        }
-        return ret;
-    }
-
-    @Specialization(guards = {"preserveNames", "preserveDimensions"})
-    protected RRawVector doLogicalVectorDimsNames(RLogicalVector operand) {
-        byte[] bdata = dataFromLogical(operand);
-        RRawVector ret = RDataFactory.createRawVector(bdata, operand.getDimensions(), operand.getNames());
-        if (isAttrPreservation()) {
-            ret.copyRegAttributesFrom(operand);
-        }
-        return ret;
-    }
-
-    @Specialization(guards = {"!preserveNames", "!preserveDimensions"})
-    protected RRawVector doLogicalVector(RLogicalVector operand) {
-        byte[] bdata = dataFromLogical(operand);
-        RRawVector ret = RDataFactory.createRawVector(bdata);
-        if (isAttrPreservation()) {
-            ret.copyRegAttributesFrom(operand);
-        }
-        return ret;
-    }
-
-    @Specialization(guards = {"!preserveNames", "preserveDimensions"})
-    protected RRawVector doStringVectorDims(RStringVector operand) {
-        byte[] bdata = dataFromString(operand);
-        RRawVector ret = RDataFactory.createRawVector(bdata, operand.getDimensions());
-        if (isAttrPreservation()) {
-            ret.copyRegAttributesFrom(operand);
-        }
-        return ret;
-    }
-
-    @Specialization(guards = {"preserveNames", "!preserveDimensions"})
-    protected RRawVector doStringVectorNames(RStringVector operand) {
-        byte[] bdata = dataFromString(operand);
-        RRawVector ret = RDataFactory.createRawVector(bdata, operand.getNames());
-        if (isAttrPreservation()) {
-            ret.copyRegAttributesFrom(operand);
-        }
-        return ret;
-    }
-
-    @Specialization(guards = {"preserveNames", "preserveDimensions"})
-    protected RRawVector doStringVectorDimsNames(RStringVector operand) {
-        byte[] bdata = dataFromString(operand);
-        RRawVector ret = RDataFactory.createRawVector(bdata, operand.getDimensions(), operand.getNames());
-        if (isAttrPreservation()) {
-            ret.copyRegAttributesFrom(operand);
-        }
-        return ret;
-    }
-
-    @Specialization(guards = {"!preserveNames", "!preserveDimensions"})
-    protected RRawVector doStringVector(RStringVector operand) {
-        byte[] bdata = dataFromString(operand);
-        RRawVector ret = RDataFactory.createRawVector(bdata);
-        if (isAttrPreservation()) {
-            ret.copyRegAttributesFrom(operand);
+    protected RRawVector doComplexVector(RComplexVector operand) {
+        byte[] bdata = new byte[operand.getLength()];
+        boolean imaginaryDiscardedWarning = false;
+        boolean outOfRangeWarning = false;
+        for (int i = 0; i < operand.getLength(); i++) {
+            RComplex complexVal = operand.getDataAt(i);
+            int intRawValue = RRuntime.complex2rawIntValue(complexVal);
+            if (complexVal.getImaginaryPart() != 0.0) {
+                imaginaryDiscardedWarning = true;
+            }
+            if ((int) complexVal.getRealPart() != intRawValue) {
+                outOfRangeWarning = true;
+            }
+            bdata[i] = (byte) intRawValue;
         }
-        return ret;
-    }
-
-    @Specialization(guards = {"!preserveNames", "preserveDimensions"})
-    protected RRawVector doRawVectorDims(RComplexVector operand) {
-        byte[] bdata = dataFromComplex(operand);
-        RRawVector ret = RDataFactory.createRawVector(bdata, operand.getDimensions());
-        if (isAttrPreservation()) {
-            ret.copyRegAttributesFrom(operand);
+        if (imaginaryDiscardedWarning) {
+            warningBranch.enter();
+            RError.warning(RError.Message.IMAGINARY_PARTS_DISCARDED_IN_COERCION);
         }
-        return ret;
-    }
-
-    @Specialization(guards = {"preserveNames", "!preserveDimensions"})
-    protected RRawVector doComplexVectorNames(RComplexVector operand) {
-        byte[] bdata = dataFromComplex(operand);
-        RRawVector ret = RDataFactory.createRawVector(bdata, operand.getNames());
-        if (isAttrPreservation()) {
-            ret.copyRegAttributesFrom(operand);
+        if (outOfRangeWarning) {
+            warningBranch.enter();
+            RError.warning(RError.Message.OUT_OF_RANGE);
         }
-        return ret;
+        return createResultVector(operand, bdata);
     }
 
-    @Specialization(guards = {"preserveNames", "preserveDimensions"})
-    protected RRawVector doComplexVectorDimsNames(RComplexVector operand) {
-        byte[] bdata = dataFromComplex(operand);
-        RRawVector ret = RDataFactory.createRawVector(bdata, operand.getDimensions(), operand.getNames());
-        if (isAttrPreservation()) {
-            ret.copyRegAttributesFrom(operand);
+    @Specialization
+    protected RRawVector doDoubleVector(RAbstractDoubleVector operand) {
+        int length = operand.getLength();
+        byte[] bdata = new byte[length];
+        boolean warning = false;
+        for (int i = 0; i < length; ++i) {
+            double doubleValue = operand.getDataAt(i);
+            int intRawValue = RRuntime.double2rawIntValue(doubleValue);
+            if (intRawValue != (int) doubleValue) {
+                warning = true;
+            }
+            bdata[i] = (byte) intRawValue;
         }
-        return ret;
-    }
-
-    @Specialization(guards = {"!preserveNames", "!preserveDimensions"})
-    protected RRawVector doComplexVector(RComplexVector operand) {
-        byte[] bdata = dataFromComplex(operand);
-        RRawVector ret = RDataFactory.createRawVector(bdata);
-        if (isAttrPreservation()) {
-            ret.copyRegAttributesFrom(operand);
+        if (warning) {
+            warningBranch.enter();
+            RError.warning(RError.Message.OUT_OF_RANGE);
         }
-        return ret;
-    }
-
-    @Specialization
-    protected RRawVector doDoubleVector(RDoubleVector value) {
-        return performAbstractDoubleVector(value);
-    }
-
-    @Specialization
-    protected RRawVector doDoubleSequence(RDoubleSequence value) {
-        return performAbstractDoubleVector(value);
+        return createResultVector(operand, bdata);
     }
 
     @Specialization
@@ -312,66 +235,4 @@ public abstract class CastRawNode extends CastNode {
     public int doOther(Object operand) {
         throw new ConversionFailedException(operand.getClass().getName());
     }
-
-    private RRawVector performAbstractIntVector(RAbstractIntVector value) {
-        int length = value.getLength();
-        byte[] array = new byte[length];
-        boolean warning = false;
-        for (int i = 0; i < length; ++i) {
-            int intValue = value.getDataAt(i);
-            int intRawValue = RRuntime.int2rawIntValue(intValue);
-            if (intRawValue != intValue) {
-                warning = true;
-            }
-            array[i] = (byte) intRawValue;
-        }
-        if (warning) {
-            RError.warning(RError.Message.OUT_OF_RANGE);
-        }
-        RRawVector ret;
-        if (preserveDimensions() && preserveNames()) {
-            ret = RDataFactory.createRawVector(array, value.getDimensions(), value.getNames());
-        } else if (preserveDimensions()) {
-            ret = RDataFactory.createRawVector(array, value.getDimensions());
-        } else if (preserveNames()) {
-            ret = RDataFactory.createRawVector(array, value.getNames());
-        } else {
-            ret = RDataFactory.createRawVector(array);
-        }
-        if (isAttrPreservation()) {
-            ret.copyRegAttributesFrom(value);
-        }
-        return ret;
-    }
-
-    private RRawVector performAbstractDoubleVector(RAbstractDoubleVector value) {
-        int length = value.getLength();
-        byte[] array = new byte[length];
-        boolean warning = false;
-        for (int i = 0; i < length; ++i) {
-            double doubleValue = value.getDataAt(i);
-            int intRawValue = RRuntime.double2rawIntValue(doubleValue);
-            if (intRawValue != (int) doubleValue) {
-                warning = true;
-            }
-            array[i] = (byte) intRawValue;
-        }
-        if (warning) {
-            RError.warning(RError.Message.OUT_OF_RANGE);
-        }
-        RRawVector ret;
-        if (preserveDimensions() && preserveNames()) {
-            ret = RDataFactory.createRawVector(array, value.getDimensions(), value.getNames());
-        } else if (preserveDimensions()) {
-            ret = RDataFactory.createRawVector(array, value.getDimensions());
-        } else if (preserveNames()) {
-            ret = RDataFactory.createRawVector(array, value.getNames());
-        } else {
-            ret = RDataFactory.createRawVector(array);
-        }
-        if (isAttrPreservation()) {
-            ret.copyRegAttributesFrom(value);
-        }
-        return ret;
-    }
 }
diff --git a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/unary/CastStringNode.java b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/unary/CastStringNode.java
index 336a953cd8cae19d2b96c553afd127f9c94a7dde..4717be1f29d280a3beb9f5f8312abfa54ac99bbc 100644
--- a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/unary/CastStringNode.java
+++ b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/unary/CastStringNode.java
@@ -22,6 +22,8 @@
  */
 package com.oracle.truffle.r.nodes.unary;
 
+import java.util.function.*;
+
 import com.oracle.truffle.api.dsl.*;
 import com.oracle.truffle.api.frame.*;
 import com.oracle.truffle.r.runtime.data.*;
@@ -30,7 +32,7 @@ import com.oracle.truffle.r.runtime.data.model.*;
 @NodeField(name = "emptyVectorConvertedToNull", type = boolean.class)
 public abstract class CastStringNode extends CastNode {
 
-    @Child private ToStringNode toString = ToStringNodeFactory.create(null);
+    @Child private ToStringNode toString = ToStringNodeFactory.create(null, false, ToStringNode.DEFAULT_SEPARATOR, false);
 
     public abstract Object executeString(VirtualFrame frame, int o);
 
@@ -42,10 +44,6 @@ public abstract class CastStringNode extends CastNode {
 
     public abstract boolean isEmptyVectorConvertedToNull();
 
-    public CastStringNode() {
-        toString.setQuotes(false);
-    }
-
     @Specialization
     protected RNull doNull(@SuppressWarnings("unused") RNull operand) {
         return RNull.instance;
@@ -76,40 +74,16 @@ public abstract class CastStringNode extends CastNode {
         return toString.executeString(frame, value);
     }
 
-    private String[] dataFromLogical(VirtualFrame frame, RLogicalVector operand) {
-        String[] sdata = new String[operand.getLength()];
-        for (int i = 0; i < operand.getLength(); i++) {
-            byte value = operand.getDataAt(i);
-            sdata[i] = toString.executeString(frame, value);
-        }
-        return sdata;
-    }
-
-    private String[] dataFromComplex(VirtualFrame frame, RComplexVector operand) {
+    private RStringVector createResultVector(RAbstractVector operand, IntFunction<String> elementFunction) {
         String[] sdata = new String[operand.getLength()];
         for (int i = 0; i < operand.getLength(); i++) {
-            RComplex value = operand.getDataAt(i);
-            sdata[i] = toString.executeString(frame, value);
+            sdata[i] = elementFunction.apply(i);
         }
-        return sdata;
-    }
-
-    private String[] dataFromRaw(VirtualFrame frame, RRawVector operand) {
-        String[] sdata = new String[operand.getLength()];
-        for (int i = 0; i < operand.getLength(); i++) {
-            RRaw value = operand.getDataAt(i);
-            sdata[i] = toString.executeString(frame, value);
-        }
-        return sdata;
-    }
-
-    private String[] dataFromList(VirtualFrame frame, RList operand) {
-        String[] sdata = new String[operand.getLength()];
-        for (int i = 0; i < operand.getLength(); i++) {
-            Object value = operand.getDataAt(i);
-            sdata[i] = toString.executeString(frame, value);
+        RStringVector ret = RDataFactory.createStringVector(sdata, RDataFactory.COMPLETE_VECTOR, isPreserveDimensions() ? operand.getDimensions() : null, isPreserveNames() ? operand.getNames() : null);
+        if (isAttrPreservation()) {
+            ret.copyRegAttributesFrom(operand);
         }
-        return sdata;
+        return ret;
     }
 
     @Specialization(guards = "isZeroLength")
@@ -123,183 +97,33 @@ public abstract class CastStringNode extends CastNode {
     }
 
     @Specialization(guards = "!isZeroLength")
-    protected RStringVector doIntVector(VirtualFrame frame, RIntVector vector) {
-        return performAbstractIntVector(frame, vector);
+    protected RStringVector doIntVector(VirtualFrame frame, RAbstractIntVector operand) {
+        return createResultVector(operand, index -> toString.executeString(frame, operand.getDataAt(index)));
     }
 
     @Specialization(guards = "!isZeroLength")
-    protected RStringVector doDoubleVector(VirtualFrame frame, RDoubleVector vector) {
-        return performAbstractDoubleVector(frame, vector);
+    protected RStringVector doDoubleVector(VirtualFrame frame, RAbstractDoubleVector operand) {
+        return createResultVector(operand, index -> toString.executeString(frame, operand.getDataAt(index)));
     }
 
     @Specialization(guards = "!isZeroLength")
-    protected RStringVector doIntSequence(VirtualFrame frame, RIntSequence vector) {
-        return performAbstractIntVector(frame, vector);
+    protected RStringVector doLogicalVector(VirtualFrame frame, RLogicalVector operand) {
+        return createResultVector(operand, index -> toString.executeString(frame, operand.getDataAt(index)));
     }
 
     @Specialization(guards = "!isZeroLength")
-    protected RStringVector doDoubleSequence(VirtualFrame frame, RDoubleSequence vector) {
-        return performAbstractDoubleVector(frame, vector);
-    }
-
-    @Specialization(guards = {"!isZeroLength", "!preserveNames", "preserveDimensions"})
-    protected RStringVector doLogicalVectorDims(VirtualFrame frame, RLogicalVector vector) {
-        String[] result = dataFromLogical(frame, vector);
-        RStringVector ret = RDataFactory.createStringVector(result, RDataFactory.COMPLETE_VECTOR, vector.getDimensions());
-        if (isAttrPreservation()) {
-            ret.copyRegAttributesFrom(vector);
-        }
-        return ret;
-    }
-
-    @Specialization(guards = {"!isZeroLength", "preserveNames", "!preserveDimensions"})
-    protected RStringVector doLogicalVectorNames(VirtualFrame frame, RLogicalVector vector) {
-        String[] result = dataFromLogical(frame, vector);
-        RStringVector ret = RDataFactory.createStringVector(result, RDataFactory.COMPLETE_VECTOR, vector.getNames());
-        if (isAttrPreservation()) {
-            ret.copyRegAttributesFrom(vector);
-        }
-        return ret;
-    }
-
-    @Specialization(guards = {"!isZeroLength", "preserveNames", "preserveDimensions"})
-    protected RStringVector doLogicalVectorDimsNames(VirtualFrame frame, RLogicalVector vector) {
-        String[] result = dataFromLogical(frame, vector);
-        RStringVector ret = RDataFactory.createStringVector(result, RDataFactory.COMPLETE_VECTOR, vector.getDimensions(), vector.getNames());
-        if (isAttrPreservation()) {
-            ret.copyRegAttributesFrom(vector);
-        }
-        return ret;
-    }
-
-    @Specialization(guards = {"!isZeroLength", "!preserveNames", "!preserveDimensions"})
-    protected RStringVector doLogicalVector(VirtualFrame frame, RLogicalVector vector) {
-        String[] result = dataFromLogical(frame, vector);
-        RStringVector ret = RDataFactory.createStringVector(result, RDataFactory.COMPLETE_VECTOR);
-        if (isAttrPreservation()) {
-            ret.copyRegAttributesFrom(vector);
-        }
-        return ret;
-    }
-
-    @Specialization(guards = {"!isZeroLength", "!preserveNames", "preserveDimensions"})
-    protected RStringVector doComplexVectorDims(VirtualFrame frame, RComplexVector vector) {
-        String[] result = dataFromComplex(frame, vector);
-        RStringVector ret = RDataFactory.createStringVector(result, RDataFactory.COMPLETE_VECTOR, vector.getDimensions());
-        if (isAttrPreservation()) {
-            ret.copyRegAttributesFrom(vector);
-        }
-        return ret;
-    }
-
-    @Specialization(guards = {"!isZeroLength", "preserveNames", "!preserveDimensions"})
-    protected RStringVector doComplexVectorNames(VirtualFrame frame, RComplexVector vector) {
-        String[] result = dataFromComplex(frame, vector);
-        RStringVector ret = RDataFactory.createStringVector(result, RDataFactory.COMPLETE_VECTOR, vector.getNames());
-        if (isAttrPreservation()) {
-            ret.copyRegAttributesFrom(vector);
-        }
-        return ret;
-    }
-
-    @Specialization(guards = {"!isZeroLength", "preserveNames", "preserveDimensions"})
-    protected RStringVector doComplexVectorDimsNames(VirtualFrame frame, RComplexVector vector) {
-        String[] result = dataFromComplex(frame, vector);
-        RStringVector ret = RDataFactory.createStringVector(result, RDataFactory.COMPLETE_VECTOR, vector.getDimensions(), vector.getNames());
-        if (isAttrPreservation()) {
-            ret.copyRegAttributesFrom(vector);
-        }
-        return ret;
-    }
-
-    @Specialization(guards = {"!isZeroLength", "!preserveNames", "!preserveDimensions"})
-    protected RStringVector doComplexVector(VirtualFrame frame, RComplexVector vector) {
-        String[] result = dataFromComplex(frame, vector);
-        RStringVector ret = RDataFactory.createStringVector(result, RDataFactory.COMPLETE_VECTOR);
-        if (isAttrPreservation()) {
-            ret.copyRegAttributesFrom(vector);
-        }
-        return ret;
-    }
-
-    @Specialization(guards = {"!isZeroLength", "!preserveNames", "preserveDimensions"})
-    protected RStringVector doRawVectorDims(VirtualFrame frame, RRawVector vector) {
-        String[] result = dataFromRaw(frame, vector);
-        RStringVector ret = RDataFactory.createStringVector(result, RDataFactory.COMPLETE_VECTOR, vector.getDimensions());
-        if (isAttrPreservation()) {
-            ret.copyRegAttributesFrom(vector);
-        }
-        return ret;
-    }
-
-    @Specialization(guards = {"!isZeroLength", "preserveNames", "!preserveDimensions"})
-    protected RStringVector doRawVectorNames(VirtualFrame frame, RRawVector vector) {
-        String[] result = dataFromRaw(frame, vector);
-        RStringVector ret = RDataFactory.createStringVector(result, RDataFactory.COMPLETE_VECTOR, vector.getNames());
-        if (isAttrPreservation()) {
-            ret.copyRegAttributesFrom(vector);
-        }
-        return ret;
-    }
-
-    @Specialization(guards = {"!isZeroLength", "preserveNames", "preserveDimensions"})
-    protected RStringVector doRawVectorDimsNames(VirtualFrame frame, RRawVector vector) {
-        String[] result = dataFromRaw(frame, vector);
-        RStringVector ret = RDataFactory.createStringVector(result, RDataFactory.COMPLETE_VECTOR, vector.getDimensions(), vector.getNames());
-        if (isAttrPreservation()) {
-            ret.copyRegAttributesFrom(vector);
-        }
-        return ret;
-    }
-
-    @Specialization(guards = {"!isZeroLength", "!preserveNames", "!preserveDimensions"})
-    protected RStringVector doRawVector(VirtualFrame frame, RRawVector vector) {
-        String[] result = dataFromRaw(frame, vector);
-        RStringVector ret = RDataFactory.createStringVector(result, RDataFactory.COMPLETE_VECTOR);
-        if (isAttrPreservation()) {
-            ret.copyRegAttributesFrom(vector);
-        }
-        return ret;
-    }
-
-    @Specialization(guards = {"!isZeroLength", "!preserveNames", "preserveDimensions"})
-    protected RStringVector doListDims(VirtualFrame frame, RList list) {
-        String[] result = dataFromList(frame, list);
-        RStringVector ret = RDataFactory.createStringVector(result, RDataFactory.COMPLETE_VECTOR, list.getDimensions());
-        if (isAttrPreservation()) {
-            ret.copyRegAttributesFrom(list);
-        }
-        return ret;
+    protected RStringVector doComplexVector(VirtualFrame frame, RComplexVector operand) {
+        return createResultVector(operand, index -> toString.executeString(frame, operand.getDataAt(index)));
     }
 
-    @Specialization(guards = {"!isZeroLength", "preserveNames", "!preserveDimensions"})
-    protected RStringVector doListNames(VirtualFrame frame, RList list) {
-        String[] result = dataFromList(frame, list);
-        RStringVector ret = RDataFactory.createStringVector(result, RDataFactory.COMPLETE_VECTOR, list.getNames());
-        if (isAttrPreservation()) {
-            ret.copyRegAttributesFrom(list);
-        }
-        return ret;
-    }
-
-    @Specialization(guards = {"!isZeroLength", "preserveNames", "preserveDimensions"})
-    protected RStringVector doListDimsNames(VirtualFrame frame, RList list) {
-        String[] result = dataFromList(frame, list);
-        RStringVector ret = RDataFactory.createStringVector(result, RDataFactory.COMPLETE_VECTOR, list.getDimensions(), list.getNames());
-        if (isAttrPreservation()) {
-            ret.copyRegAttributesFrom(list);
-        }
-        return ret;
+    @Specialization(guards = "!isZeroLength")
+    protected RStringVector doRawVector(VirtualFrame frame, RRawVector operand) {
+        return createResultVector(operand, index -> toString.executeString(frame, operand.getDataAt(index)));
     }
 
-    @Specialization(guards = {"!isZeroLength", "!preserveNames", "!preserveDimensions"})
-    protected RStringVector doList(VirtualFrame frame, RList list) {
-        String[] result = dataFromList(frame, list);
-        RStringVector ret = RDataFactory.createStringVector(result, RDataFactory.COMPLETE_VECTOR);
-        if (isAttrPreservation()) {
-            ret.copyRegAttributesFrom(list);
-        }
-        return ret;
+    @Specialization(guards = "!isZeroLength")
+    protected RStringVector doList(VirtualFrame frame, RList operand) {
+        return createResultVector(operand, index -> toString.executeString(frame, operand.getDataAt(index)));
     }
 
     @Specialization
@@ -307,50 +131,7 @@ public abstract class CastStringNode extends CastNode {
         return s.getName();
     }
 
-    private RStringVector performAbstractIntVector(VirtualFrame frame, RAbstractIntVector vector) {
-        int length = vector.getLength();
-        String[] result = new String[length];
-        for (int i = 0; i < length; i++) {
-            result[i] = toString.executeString(frame, vector.getDataAt(i));
-        }
-        RStringVector ret;
-        if (preserveDimensions()) {
-            ret = RDataFactory.createStringVector(result, RDataFactory.COMPLETE_VECTOR, vector.getDimensions());
-        } else if (preserveNames()) {
-            ret = RDataFactory.createStringVector(result, RDataFactory.COMPLETE_VECTOR, vector.getNames());
-        } else {
-            ret = RDataFactory.createStringVector(result, RDataFactory.COMPLETE_VECTOR);
-        }
-        if (isAttrPreservation()) {
-            ret.copyRegAttributesFrom(vector);
-        }
-        return ret;
-    }
-
-    private RStringVector performAbstractDoubleVector(VirtualFrame frame, RAbstractDoubleVector vector) {
-        int length = vector.getLength();
-        String[] result = new String[length];
-        for (int i = 0; i < length; i++) {
-            result[i] = toString.executeString(frame, vector.getDataAt(i));
-        }
-        RStringVector ret;
-        if (preserveDimensions() && preserveNames()) {
-            ret = RDataFactory.createStringVector(result, RDataFactory.COMPLETE_VECTOR, vector.getDimensions(), vector.getNames());
-        } else if (preserveDimensions()) {
-            ret = RDataFactory.createStringVector(result, RDataFactory.COMPLETE_VECTOR, vector.getDimensions());
-        } else if (preserveNames()) {
-            ret = RDataFactory.createStringVector(result, RDataFactory.COMPLETE_VECTOR, vector.getNames());
-        } else {
-            ret = RDataFactory.createStringVector(result, RDataFactory.COMPLETE_VECTOR);
-        }
-        if (isAttrPreservation()) {
-            ret.copyRegAttributesFrom(vector);
-        }
-        return ret;
-    }
-
     protected boolean isZeroLength(RAbstractVector vector) {
         return vector.getLength() == 0;
     }
-
 }
diff --git a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/unary/CastSymbolNode.java b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/unary/CastSymbolNode.java
index a259c8413429806b16a27468ac972b4f13617d4b..e85dc40662ae128ec3eb11a52e7955bdc114c287 100644
--- a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/unary/CastSymbolNode.java
+++ b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/unary/CastSymbolNode.java
@@ -28,15 +28,14 @@ import com.oracle.truffle.api.frame.*;
 import com.oracle.truffle.r.runtime.*;
 import com.oracle.truffle.r.runtime.data.*;
 
-@NodeField(name = "emptyVectorConvertedToNull", type = boolean.class)
 public abstract class CastSymbolNode extends CastNode {
-    @Child private ToStringNode toString = ToStringNodeFactory.create(null);
+
+    @Child private ToStringNode toString = ToStringNodeFactory.create(null, true, ToStringNode.DEFAULT_SEPARATOR, false);
 
     public abstract Object executeSymbol(VirtualFrame frame, Object o);
 
-    @SuppressWarnings("unused")
     @Specialization
-    protected RSymbol doNull(RNull value) {
+    protected RSymbol doNull(@SuppressWarnings("unused") RNull value) {
         throw RError.error(getEncapsulatingSourceSection(), RError.Message.INVALID_TYPE_LENGTH, "symbol", 0);
     }
 
@@ -61,7 +60,7 @@ public abstract class CastSymbolNode extends CastNode {
     }
 
     @Specialization
-    protected RSymbol doStringVector(@SuppressWarnings("unused") VirtualFrame frame, RStringVector value) {
+    protected RSymbol doStringVector(RStringVector value) {
         // Only element 0 interpreted
         return doString(value.getDataAt(0));
     }
@@ -85,5 +84,4 @@ public abstract class CastSymbolNode extends CastNode {
     private static RSymbol backQuote(String s) {
         return RDataFactory.createSymbol("`" + s + "`");
     }
-
 }
diff --git a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/unary/CastToContainerNode.java b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/unary/CastToContainerNode.java
index bd1ff7d31e5f95fe2a70b0f86c65db87362e1ac8..5b03886ca5b28b2c524d194c7b2934a84730775c 100644
--- a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/unary/CastToContainerNode.java
+++ b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/unary/CastToContainerNode.java
@@ -58,8 +58,7 @@ public abstract class CastToContainerNode extends CastNode {
     }
 
     @Specialization(guards = "!preserveNonContainer")
-    @SuppressWarnings("unused")
-    protected RAbstractVector cast(RFunction f) {
+    protected RAbstractVector cast(@SuppressWarnings("unused") RFunction f) {
         return RDataFactory.createList();
     }
 
@@ -87,5 +86,4 @@ public abstract class CastToContainerNode extends CastNode {
     protected RPairList cast(RPairList pairlist) {
         return pairlist;
     }
-
 }
diff --git a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/unary/CastToVectorNode.java b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/unary/CastToVectorNode.java
index 1265f614724f7df9d285e3cdb5aa146771ca0327..ef73dffc189cf3f2fa66b96298bb4ba9c00c5cef 100644
--- a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/unary/CastToVectorNode.java
+++ b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/unary/CastToVectorNode.java
@@ -39,14 +39,12 @@ public abstract class CastToVectorNode extends CastNode {
     }
 
     @Specialization(guards = "preserveNonVector")
-    @SuppressWarnings("unused")
-    protected RNull castNull(RNull rnull) {
+    protected RNull castNull(@SuppressWarnings("unused") RNull rnull) {
         return RNull.instance;
     }
 
     @Specialization(guards = "!preserveNonVector")
-    @SuppressWarnings("unused")
-    protected RAbstractVector cast(RNull rnull) {
+    protected RAbstractVector cast(@SuppressWarnings("unused") RNull rnull) {
         return RDataFactory.createList();
     }
 
@@ -56,8 +54,7 @@ public abstract class CastToVectorNode extends CastNode {
     }
 
     @Specialization(guards = "!preserveNonVector")
-    @SuppressWarnings("unused")
-    protected RAbstractVector cast(RFunction f) {
+    protected RAbstractVector cast(@SuppressWarnings("unused") RFunction f) {
         return RDataFactory.createList();
     }
 
@@ -65,5 +62,4 @@ public abstract class CastToVectorNode extends CastNode {
     protected RAbstractVector cast(RAbstractVector vector) {
         return vector;
     }
-
 }
diff --git a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/unary/ConvertNode.java b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/unary/ConversionFailedException.java
similarity index 74%
rename from com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/unary/ConvertNode.java
rename to com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/unary/ConversionFailedException.java
index b2467a7ae8d4fcaa581ab8fa6ae7f9fe90cf92b7..f73ca2e54dd03b88da7da8963c379adb98eb61bf 100644
--- a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/unary/ConvertNode.java
+++ b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/unary/ConversionFailedException.java
@@ -22,17 +22,12 @@
  */
 package com.oracle.truffle.r.nodes.unary;
 
-public abstract class ConvertNode extends UnaryNode {
+/** Thrown by a convert node. Indicates that a parent node must rewrite itself. */
+public final class ConversionFailedException extends RuntimeException {
 
-    /** Thrown by a convert node. Indicates that a parent node must rewrite itself. */
-    public static final class ConversionFailedException extends RuntimeException {
-
-        private static final long serialVersionUID = 1L;
-
-        public ConversionFailedException(String message) {
-            super(message);
-        }
+    private static final long serialVersionUID = 1L;
 
+    public ConversionFailedException(String message) {
+        super(message);
     }
-
 }
diff --git a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/unary/ConvertBooleanNode.java b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/unary/ConvertBooleanNode.java
index 62752158abcdedcd75b8b2f736a31f29e8f29b2b..bfb6bbe3f0cdd36fd158bc73bc064e00ad6d6de9 100644
--- a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/unary/ConvertBooleanNode.java
+++ b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/unary/ConvertBooleanNode.java
@@ -33,7 +33,9 @@ import com.oracle.truffle.r.runtime.ops.na.*;
 
 public abstract class ConvertBooleanNode extends UnaryNode {
 
-    private final NACheck check = NACheck.create();
+    private final NAProfile naProfile = NAProfile.create();
+    private final BranchProfile invalidElementCountBranch = BranchProfile.create();
+    private final BranchProfile errorBranch = BranchProfile.create();
 
     @Override
     public abstract byte executeByte(VirtualFrame frame);
@@ -41,47 +43,41 @@ public abstract class ConvertBooleanNode extends UnaryNode {
     public abstract byte executeByte(VirtualFrame frame, Object operandValue);
 
     @Specialization
-    protected byte doLogical(byte value) {
-        check.enable(value);
-        if (check.check(value)) {
-            throw RError.error(getEncapsulatingSourceSection(), RError.Message.NA_UNEXP);
+    protected byte doInt(int value) {
+        if (naProfile.isNA(value)) {
+            throw RError.error(getEncapsulatingSourceSection(), RError.Message.ARGUMENT_NOT_INTERPRETABLE_LOGICAL);
         }
-        return value;
+        return RRuntime.int2logicalNoCheck(value);
     }
 
     @Specialization
-    protected byte doInt(int value) {
-        check.enable(value);
-        if (check.check(value)) {
+    protected byte doDouble(double value) {
+        if (naProfile.isNA(value)) {
             throw RError.error(getEncapsulatingSourceSection(), RError.Message.ARGUMENT_NOT_INTERPRETABLE_LOGICAL);
         }
-        return RRuntime.asLogical(value != 0);
+        return RRuntime.double2logicalNoCheck(value);
     }
 
     @Specialization
-    protected byte doDouble(double value) {
-        check.enable(value);
-        if (check.check(value)) {
-            throw RError.error(getEncapsulatingSourceSection(), RError.Message.ARGUMENT_NOT_INTERPRETABLE_LOGICAL);
+    protected byte doLogical(byte value) {
+        if (naProfile.isNA(value)) {
+            throw RError.error(getEncapsulatingSourceSection(), RError.Message.NA_UNEXP);
         }
-        return RRuntime.asLogical(value != 0D);
+        return value;
     }
 
     @Specialization
     protected byte doComplex(RComplex value) {
-        check.enable(value);
-        if (check.check(value)) {
+        if (naProfile.isNA(value)) {
             throw RError.error(getEncapsulatingSourceSection(), RError.Message.ARGUMENT_NOT_INTERPRETABLE_LOGICAL);
         }
-        return RRuntime.asLogical(!value.isZero());
+        return RRuntime.complex2logicalNoCheck(value);
     }
 
     @Specialization
     protected byte doString(String value) {
-        check.enable(value);
-        byte logicalValue = check.convertStringToLogical(value);
-        check.enable(logicalValue);
-        if (check.check(logicalValue)) {
+        byte logicalValue = RRuntime.string2logicalNoCheck(value);
+        if (naProfile.isNA(logicalValue)) {
             throw RError.error(getEncapsulatingSourceSection(), RError.Message.ARGUMENT_NOT_INTERPRETABLE_LOGICAL);
         }
         return logicalValue;
@@ -89,113 +85,55 @@ public abstract class ConvertBooleanNode extends UnaryNode {
 
     @Specialization
     protected byte doRaw(RRaw value) {
-        return RRuntime.asLogical(value.getValue() != 0);
+        return RRuntime.raw2logical(value);
     }
 
-    @Specialization
-    protected byte doIntSequence(RIntSequence value) {
-        if (value.getLength() > 1) {
-            moreThanOneElem.enter();
-            RError.warning(this.getEncapsulatingSourceSection(), RError.Message.LENGTH_GT_1);
+    private void checkLength(RAbstractVector value) {
+        if (value.getLength() != 1) {
+            invalidElementCountBranch.enter();
+            if (value.getLength() == 0) {
+                errorBranch.enter();
+                throw RError.error(getEncapsulatingSourceSection(), RError.Message.LENGTH_ZERO);
+            } else {
+                RError.warning(getEncapsulatingSourceSection(), RError.Message.LENGTH_GT_1);
+            }
         }
-        return RRuntime.asLogical(value.getStart() != 0);
     }
 
     @Specialization
-    protected byte doDoubleSequence(RDoubleSequence value) {
-        if (value.getLength() > 1) {
-            moreThanOneElem.enter();
-            RError.warning(this.getEncapsulatingSourceSection(), RError.Message.LENGTH_GT_1);
-        }
-        return RRuntime.asLogical(value.getStart() != 0D);
-    }
-
-    @SuppressWarnings("unused")
-    @Specialization(guards = "isEmpty")
-    protected byte doEmptyVector(RAbstractVector value) {
-        throw RError.error(this.getEncapsulatingSourceSection(), RError.Message.LENGTH_ZERO);
+    protected byte doIntVector(RAbstractIntVector value) {
+        checkLength(value);
+        return doInt(value.getDataAt(0));
     }
 
-    private final BranchProfile moreThanOneElem = BranchProfile.create();
-
-    @Specialization(guards = "!isEmpty")
-    protected byte doIntVector(RIntVector value) {
-        if (value.getLength() > 1) {
-            moreThanOneElem.enter();
-            RError.warning(this.getEncapsulatingSourceSection(), RError.Message.LENGTH_GT_1);
-        }
-        check.enable(value);
-        if (check.check(value.getDataAt(0))) {
-            throw RError.error(getEncapsulatingSourceSection(), RError.Message.ARGUMENT_NOT_INTERPRETABLE_LOGICAL);
-        }
-        return RRuntime.asLogical(value.getDataAt(0) != 0);
-    }
-
-    @Specialization(guards = "!isEmpty")
-    protected byte doDoubleVector(RDoubleVector value) {
-        if (value.getLength() > 1) {
-            moreThanOneElem.enter();
-            RError.warning(this.getEncapsulatingSourceSection(), RError.Message.LENGTH_GT_1);
-        }
-        check.enable(value);
-        if (check.check(value.getDataAt(0))) {
-            throw RError.error(getEncapsulatingSourceSection(), RError.Message.ARGUMENT_NOT_INTERPRETABLE_LOGICAL);
-        }
-        return RRuntime.asLogical(value.getDataAt(0) != 0D);
+    @Specialization
+    protected byte doDoubleVector(RAbstractDoubleVector value) {
+        checkLength(value);
+        return doDouble(value.getDataAt(0));
     }
 
-    @Specialization(guards = "!isEmpty")
+    @Specialization
     protected byte doLogicalVector(RLogicalVector value) {
-        if (value.getLength() > 1) {
-            moreThanOneElem.enter();
-            RError.warning(this.getEncapsulatingSourceSection(), RError.Message.LENGTH_GT_1);
-        }
-        check.enable(value);
-        if (check.check(value.getDataAt(0))) {
-            throw RError.error(getEncapsulatingSourceSection(), RError.Message.NA_UNEXP);
-        }
-        return RRuntime.asLogical(value.getDataAt(0) != RRuntime.LOGICAL_FALSE);
+        checkLength(value);
+        return doLogical(value.getDataAt(0));
     }
 
-    @Specialization(guards = "!isEmpty")
+    @Specialization
     protected byte doComplexVector(RComplexVector value) {
-        if (value.getLength() > 1) {
-            moreThanOneElem.enter();
-            RError.warning(this.getEncapsulatingSourceSection(), RError.Message.LENGTH_GT_1);
-        }
-        check.enable(value);
-        if (check.check(value.getDataAt(0))) {
-            throw RError.error(getEncapsulatingSourceSection(), RError.Message.ARGUMENT_NOT_INTERPRETABLE_LOGICAL);
-        }
-        return RRuntime.asLogical(!value.getDataAt(0).isZero());
+        checkLength(value);
+        return doComplex(value.getDataAt(0));
     }
 
-    @Specialization(guards = "!isEmpty")
-    protected byte doRawVector(RRawVector value) {
-        if (value.getLength() > 1) {
-            moreThanOneElem.enter();
-            RError.warning(this.getEncapsulatingSourceSection(), RError.Message.LENGTH_GT_1);
-        }
-        return RRuntime.asLogical(value.getDataAt(0).getValue() != 0);
-    }
-
-    @Specialization(guards = "!isEmpty")
+    @Specialization
     protected byte doStringVector(RStringVector value) {
-        if (value.getLength() > 1) {
-            moreThanOneElem.enter();
-            RError.warning(this.getEncapsulatingSourceSection(), RError.Message.LENGTH_GT_1);
-        }
-        check.enable(value);
-        byte logicalValue = check.convertStringToLogical(value.getDataAt(0));
-        check.enable(logicalValue);
-        if (check.check(logicalValue)) {
-            throw RError.error(getEncapsulatingSourceSection(), RError.Message.ARGUMENT_NOT_INTERPRETABLE_LOGICAL);
-        }
-        return logicalValue;
+        checkLength(value);
+        return doString(value.getDataAt(0));
     }
 
-    protected boolean isEmpty(RAbstractVector vector) {
-        return vector.getLength() == 0;
+    @Specialization
+    protected byte doRawVector(RRawVector value) {
+        checkLength(value);
+        return doRaw(value.getDataAt(0));
     }
 
     public static ConvertBooleanNode create(RNode node) {
diff --git a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/unary/ConvertInt.java b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/unary/ConvertInt.java
index 23120f161e24efd8692edf5d6fd748353c311d09..87f054d849e832b191626e2955788b845ee07e5d 100644
--- a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/unary/ConvertInt.java
+++ b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/unary/ConvertInt.java
@@ -25,17 +25,10 @@ package com.oracle.truffle.r.nodes.unary;
 import com.oracle.truffle.api.CompilerDirectives.TruffleBoundary;
 import com.oracle.truffle.api.dsl.*;
 import com.oracle.truffle.api.frame.*;
-import com.oracle.truffle.r.nodes.unary.ConvertNode.ConversionFailedException;
 import com.oracle.truffle.r.runtime.*;
 
-//@PolymorphicLimit(1)
 public abstract class ConvertInt extends UnaryNode {
 
-    @Override
-    public abstract int executeInteger(VirtualFrame frame);
-
-    public abstract Object execute(VirtualFrame frame, Object operand);
-
     public abstract int executeInteger(VirtualFrame frame, Object operand);
 
     @Specialization
diff --git a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/unary/ConvertIntExact.java b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/unary/ConvertIntExact.java
deleted file mode 100644
index 3bacef7794b80d3adc5f7b3d0bee56699c7e46d4..0000000000000000000000000000000000000000
--- a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/unary/ConvertIntExact.java
+++ /dev/null
@@ -1,68 +0,0 @@
-/*
- * Copyright (c) 2013, 2014, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-package com.oracle.truffle.r.nodes.unary;
-
-import com.oracle.truffle.api.CompilerDirectives.TruffleBoundary;
-import com.oracle.truffle.api.dsl.*;
-import com.oracle.truffle.api.frame.*;
-import com.oracle.truffle.r.nodes.unary.ConvertNode.ConversionFailedException;
-import com.oracle.truffle.r.runtime.*;
-import com.oracle.truffle.r.runtime.data.*;
-
-//@PolymorphicLimit(1)
-public abstract class ConvertIntExact extends UnaryNode {
-
-    public abstract Object execute(VirtualFrame frame, Object operand);
-
-    public abstract int executeInteger(VirtualFrame frame, Object operand);
-
-    @Specialization
-    protected int doInt(int operand) {
-        return operand;
-    }
-
-    @Specialization
-    protected int doLogical(byte operand) {
-        return RRuntime.logical2int(operand);
-    }
-
-    @Specialization
-    protected double doInt(RIntVector operand) {
-        if (operand.getLength() == 1) {
-            return operand.getDataAt(0);
-        } else {
-            throw fail(operand.getClass().getName());
-        }
-    }
-
-    @Fallback
-    public int doOther(Object operand) {
-        throw fail(operand.getClass().getName());
-    }
-
-    @TruffleBoundary
-    private static ConversionFailedException fail(String className) {
-        throw new ConversionFailedException(className);
-    }
-
-}
diff --git a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/unary/InheritsNode.java b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/unary/InheritsNode.java
index 15c0e4ee65ec6fab870ede16cdc3f5cd2923ff3a..6c00b5e208f2c403a5b5755f93f7e8a4d818a653 100644
--- a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/unary/InheritsNode.java
+++ b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/unary/InheritsNode.java
@@ -16,6 +16,7 @@ import java.util.*;
 import com.oracle.truffle.api.CompilerDirectives.TruffleBoundary;
 import com.oracle.truffle.api.dsl.*;
 import com.oracle.truffle.api.frame.*;
+import com.oracle.truffle.api.utilities.*;
 import com.oracle.truffle.r.nodes.binary.*;
 import com.oracle.truffle.r.runtime.*;
 import com.oracle.truffle.r.runtime.data.*;
@@ -26,6 +27,9 @@ import com.oracle.truffle.r.runtime.env.*;
  * Basic support for "inherits" that is used by the {@code inherits} builtin and others.
  */
 public abstract class InheritsNode extends BinaryNode {
+
+    private final ConditionProfile sizeOneProfile = ConditionProfile.createBinaryProfile();
+
     public abstract byte execute(VirtualFrame frame, Object x, Object what);
 
     @SuppressWarnings("unused")
@@ -40,27 +44,43 @@ public abstract class InheritsNode extends BinaryNode {
         return RRuntime.LOGICAL_FALSE;
     }
 
-    // map operations lead to recursion resulting in compilation failure
     @Specialization
     protected Object doesInherit(RAbstractContainer x, RAbstractStringVector what) {
-        Map<String, Integer> classToPos = initClassToPos(x);
-        for (int i = 0; i < what.getLength(); ++i) {
-            if (classToPos.get(what.getDataAt(i)) != null) {
-                return RRuntime.LOGICAL_TRUE;
+        return checkDoesInherit(x.getClassHierarchy(), what);
+    }
+
+    @Specialization
+    protected Object doesInherit(RConnection x, RAbstractStringVector what) {
+        return checkDoesInherit(x.getClassHierarchy(), what);
+    }
+
+    private byte checkDoesInherit(RStringVector classHr, RAbstractStringVector what) {
+        if (sizeOneProfile.profile(what.getLength() == 1)) {
+            String whatString = what.getDataAt(0);
+            for (int i = 0; i < classHr.getLength(); ++i) {
+                if (whatString.equals(classHr.getDataAt(i))) {
+                    return RRuntime.LOGICAL_TRUE;
+                }
+            }
+        } else {
+            Map<String, Integer> classToPos = initClassToPos(classHr);
+            for (int i = 0; i < what.getLength(); ++i) {
+                if (classToPos.get(what.getDataAt(i)) != null) {
+                    return RRuntime.LOGICAL_TRUE;
+                }
             }
         }
         return RRuntime.LOGICAL_FALSE;
     }
 
+    // map operations lead to recursion resulting in compilation failure
     @TruffleBoundary
-    public static Map<String, Integer> initClassToPos(RAbstractContainer x) {
-        RStringVector klass = x.getClassHierarchy();
-
+    public static HashMap<String, Integer> initClassToPos(RStringVector classHr) {
         // Create a mapping for elements to their respective positions
         // in the vector for faster lookup.
-        Map<String, Integer> classToPos = new HashMap<>();
-        for (int i = 0; i < klass.getLength(); ++i) {
-            classToPos.put(klass.getDataAt(i), i);
+        HashMap<String, Integer> classToPos = new HashMap<>();
+        for (int i = 0; i < classHr.getLength(); ++i) {
+            classToPos.put(classHr.getDataAt(i), i);
         }
         return classToPos;
     }
diff --git a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/unary/ToStringNode.java b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/unary/ToStringNode.java
index 8d6f00e2784395b844f6698d6812c2afd0768775..87adc3278cafbb79c4be9c13f13a20f083ef35c8 100644
--- a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/unary/ToStringNode.java
+++ b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/unary/ToStringNode.java
@@ -22,6 +22,8 @@
  */
 package com.oracle.truffle.r.nodes.unary;
 
+import java.util.function.*;
+
 import com.oracle.truffle.api.*;
 import com.oracle.truffle.api.CompilerDirectives.CompilationFinal;
 import com.oracle.truffle.api.CompilerDirectives.TruffleBoundary;
@@ -29,25 +31,27 @@ import com.oracle.truffle.api.dsl.*;
 import com.oracle.truffle.api.frame.*;
 import com.oracle.truffle.r.runtime.*;
 import com.oracle.truffle.r.runtime.data.*;
+import com.oracle.truffle.r.runtime.data.model.*;
 import com.oracle.truffle.r.runtime.env.*;
 
+@NodeFields({@NodeField(name = "quotes", type = boolean.class), @NodeField(name = "separator", type = String.class), @NodeField(name = "appendIntL", type = boolean.class)})
 public abstract class ToStringNode extends UnaryNode {
 
+    public static final String DEFAULT_SEPARATOR = ", ";
+
     @Child private ToStringNode recursiveToString;
+    @CompilationFinal private Boolean separatorContainsNewlineCache;
 
-    @CompilationFinal private boolean quotes = true;
+    protected abstract boolean isQuotes();
 
-    @CompilationFinal private String separator;
+    protected abstract String getSeparator();
 
-    @CompilationFinal private boolean intL = false;
+    protected abstract boolean isAppendIntL();
 
     private String toStringRecursive(VirtualFrame frame, Object o) {
         if (recursiveToString == null) {
             CompilerDirectives.transferToInterpreterAndInvalidate();
-            recursiveToString = insert(ToStringNodeFactory.create(null));
-            recursiveToString.setSeparator(separator);
-            recursiveToString.setQuotes(quotes);
-            recursiveToString.setIntL(intL);
+            recursiveToString = insert(ToStringNodeFactory.create(null, isQuotes(), getSeparator(), isAppendIntL()));
         }
         return recursiveToString.executeString(frame, o);
     }
@@ -55,26 +59,6 @@ public abstract class ToStringNode extends UnaryNode {
     // FIXME custom separators require breaking some rules
     // FIXME separator should be a @NodeField - not possible as default values cannot be set
 
-    public ToStringNode() {
-        this.separator = DEFAULT_SEPARATOR;
-    }
-
-    public ToStringNode(ToStringNode prev) {
-        this.separator = prev.separator;
-        this.quotes = prev.quotes;
-        this.intL = prev.intL;
-    }
-
-    public static final String DEFAULT_SEPARATOR = ", ";
-
-    public final void setSeparator(String separator) {
-        this.separator = separator;
-    }
-
-    public final void setIntL(boolean intL) {
-        this.intL = intL;
-    }
-
     @Override
     public abstract String execute(VirtualFrame frame);
 
@@ -87,7 +71,7 @@ public abstract class ToStringNode extends UnaryNode {
         if (RRuntime.isNA(value)) {
             return value;
         }
-        if (quotes) {
+        if (isQuotes()) {
             return RRuntime.quoteString(value);
         }
         return value;
@@ -116,7 +100,7 @@ public abstract class ToStringNode extends UnaryNode {
 
     @Specialization
     protected String toString(int operand) {
-        return RRuntime.intToString(operand, intL);
+        return RRuntime.intToString(operand, isAppendIntL());
     }
 
     @Specialization
@@ -130,132 +114,68 @@ public abstract class ToStringNode extends UnaryNode {
     }
 
     @TruffleBoundary
-    @Specialization
-    protected String toString(RIntVector vector) {
+    private String createResultForVector(RAbstractVector vector, String empty, IntFunction<String> elementFunction) {
         int length = vector.getLength();
         if (length == 0) {
-            return "integer(0)";
+            return empty;
         }
         StringBuilder b = new StringBuilder();
         for (int i = 0; i < length; i++) {
-            b.append(toString(vector.getDataAt(i)));
-            if (i < length - 1) {
-                b.append(separator);
+            if (i > 0) {
+                b.append(getSeparator());
             }
+            b.append(elementFunction.apply(i));
         }
         return RRuntime.toString(b);
     }
 
+    @Specialization
+    protected String toString(RIntVector vector) {
+        return createResultForVector(vector, "integer(0)", index -> toString(vector.getDataAt(index)));
+    }
+
     @TruffleBoundary
     @Specialization
     protected String toString(RDoubleVector vector) {
-        int length = vector.getLength();
-        if (length == 0) {
-            return "numeric(0)";
-        }
-        StringBuilder b = new StringBuilder();
-        for (int i = 0; i < length; i++) {
-            b.append(toString(vector.getDataAt(i)));
-            if (i < length - 1) {
-                b.append(separator);
-            }
-        }
-        return RRuntime.toString(b);
+        return createResultForVector(vector, "numeric(0)", index -> toString(vector.getDataAt(index)));
     }
 
     @TruffleBoundary
     @Specialization
     protected String toString(RStringVector vector) {
-        int length = vector.getLength();
-        if (length == 0) {
-            return "character(0)";
-        }
-        StringBuilder b = new StringBuilder();
-        for (int i = 0; i < length; ++i) {
-            b.append(toString(vector.getDataAt(i)));
-            if (i < length - 1) {
-                b.append(separator);
-            }
-        }
-        return RRuntime.toString(b);
+        return createResultForVector(vector, "character(0)", index -> toString(vector.getDataAt(index)));
     }
 
-    @TruffleBoundary
     @Specialization
     protected String toString(RLogicalVector vector) {
-        int length = vector.getLength();
-        if (length == 0) {
-            return "logical(0)";
-        }
-        StringBuilder b = new StringBuilder();
-        for (int i = 0; i < length; ++i) {
-            b.append(toString(vector.getDataAt(i)));
-            if (i < length - 1) {
-                b.append(separator);
-            }
-        }
-        return RRuntime.toString(b);
+        return createResultForVector(vector, "logical(0)", index -> toString(vector.getDataAt(index)));
     }
 
-    @TruffleBoundary
     @Specialization
     protected String toString(RRawVector vector) {
-        int length = vector.getLength();
-        if (length == 0) {
-            return "raw(0)";
-        }
-        StringBuilder b = new StringBuilder();
-        for (int i = 0; i < length; ++i) {
-            b.append(toString(vector.getDataAt(i)));
-            if (i < length - 1) {
-                b.append(separator);
-            }
-        }
-        return RRuntime.toString(b);
+        return createResultForVector(vector, "raw(0)", index -> toString(vector.getDataAt(index)));
     }
 
-    @TruffleBoundary
     @Specialization
     protected String toString(RComplexVector vector) {
-        int length = vector.getLength();
-        if (length == 0) {
-            return "complex(0)";
-        }
-        StringBuilder b = new StringBuilder();
-        for (int i = 0; i < length; ++i) {
-            b.append(toString(vector.getDataAt(i)));
-            if (i < length - 1) {
-                b.append(separator);
-            }
-        }
-        return RRuntime.toString(b);
+        return createResultForVector(vector, "complex(0)", index -> toString(vector.getDataAt(index)));
     }
 
-    @TruffleBoundary
     @Specialization
     protected String toString(VirtualFrame frame, RList vector) {
-        int length = vector.getLength();
-        if (length == 0) {
-            return "list()";
-        }
-        StringBuilder b = new StringBuilder();
-        for (int i = 0; i < length; ++i) {
-            Object value = vector.getDataAt(i);
+        return createResultForVector(vector, "list()", index -> {
+            Object value = vector.getDataAt(index);
             if (value instanceof RList) {
                 RList l = (RList) value;
                 if (l.getLength() == 0) {
-                    b.append("list()");
+                    return "list()";
                 } else {
-                    b.append("list(").append(toStringRecursive(frame, l)).append(')');
+                    return "list(" + toStringRecursive(frame, l) + ')';
                 }
             } else {
-                b.append(toStringRecursive(frame, value));
-            }
-            if (i < length - 1) {
-                b.append(separator);
+                return toStringRecursive(frame, value);
             }
-        }
-        return RRuntime.toString(b);
+        });
     }
 
     @Specialization
@@ -272,8 +192,4 @@ public abstract class ToStringNode extends UnaryNode {
     protected String toString(REnvironment env) {
         return env.toString();
     }
-
-    public void setQuotes(boolean quotes) {
-        this.quotes = quotes;
-    }
 }
diff --git a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/unary/UnaryArithmeticNode.java b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/unary/UnaryArithmeticNode.java
index 3ef99e4131fb6d7aa9c5df4ae4ca313d7c4f9e39..71ba384bec71689ff9039d84ef8f03ddc292ab51 100644
--- a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/unary/UnaryArithmeticNode.java
+++ b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/unary/UnaryArithmeticNode.java
@@ -26,6 +26,7 @@ import com.oracle.truffle.api.CompilerDirectives.TruffleBoundary;
 import com.oracle.truffle.api.dsl.*;
 import com.oracle.truffle.api.frame.*;
 import com.oracle.truffle.r.runtime.*;
+import com.oracle.truffle.r.runtime.RError.Message;
 import com.oracle.truffle.r.runtime.data.*;
 import com.oracle.truffle.r.runtime.data.closures.*;
 import com.oracle.truffle.r.runtime.data.model.*;
@@ -36,56 +37,41 @@ public abstract class UnaryArithmeticNode extends UnaryNode {
 
     private final UnaryArithmetic arithmetic;
 
+    private final NAProfile naProfile = NAProfile.create();
     private final NACheck na = NACheck.create();
 
-    public UnaryArithmeticNode(UnaryArithmeticFactory factory) {
+    private final Message error;
+
+    public UnaryArithmeticNode(UnaryArithmeticFactory factory, Message error) {
         this.arithmetic = factory.create();
+        this.error = error;
     }
 
     public UnaryArithmeticNode(UnaryArithmeticNode prev) {
         this.arithmetic = prev.arithmetic;
+        this.error = prev.error;
     }
 
     public abstract Object execute(VirtualFrame frame, Object operand);
 
-    @Specialization(guards = "!isNA")
+    @Specialization
     protected int doInt(int operand) {
-        return arithmetic.op(operand);
+        return naProfile.isNA(operand) ? RRuntime.INT_NA : arithmetic.op(operand);
     }
 
-    @Specialization(guards = "isNA")
-    protected int doIntNA(@SuppressWarnings("unused") int operand) {
-        return RRuntime.INT_NA;
-    }
-
-    @Specialization(guards = "!isNA")
+    @Specialization
     protected double doDouble(double operand) {
-        return arithmetic.op(operand);
+        return naProfile.isNA(operand) ? RRuntime.DOUBLE_NA : arithmetic.op(operand);
     }
 
-    @Specialization(guards = "isNA")
-    protected double doDoubleNA(@SuppressWarnings("unused") double operand) {
-        return RRuntime.DOUBLE_NA;
-    }
-
-    @Specialization(guards = "!isNA")
+    @Specialization
     protected RComplex doComplex(RComplex operand) {
-        return arithmetic.op(operand.getRealPart(), operand.getImaginaryPart());
+        return naProfile.isNA(operand) ? RRuntime.createComplexNA() : arithmetic.op(operand.getRealPart(), operand.getImaginaryPart());
     }
 
-    @Specialization(guards = "isNA")
-    protected RComplex doComplexNA(@SuppressWarnings("unused") RComplex operand) {
-        return RRuntime.createComplexNA();
-    }
-
-    @Specialization(guards = "!isNA")
+    @Specialization
     protected int doLogical(byte operand) {
-        return arithmetic.op(operand);
-    }
-
-    @Specialization(guards = "isNA")
-    protected int doLogicalNA(@SuppressWarnings("unused") byte operand) {
-        return RRuntime.INT_NA;
+        return naProfile.isNA(operand) ? RRuntime.INT_NA : arithmetic.op(operand);
     }
 
     @TruffleBoundary
@@ -188,14 +174,9 @@ public abstract class UnaryArithmeticNode extends UnaryNode {
         return doIntVectorNA(RClosures.createLogicalToIntVector(operands, na));
     }
 
-    @Specialization
-    protected Object doStringVector(@SuppressWarnings("unused") RAbstractStringVector operands) {
-        throw RError.error(getEncapsulatingSourceSection(), RError.Message.INVALID_ARG_TYPE_UNARY);
-    }
-
-    @Specialization
-    protected Object doRawVector(@SuppressWarnings("unused") RAbstractRawVector operands) {
-        throw RError.error(getEncapsulatingSourceSection(), RError.Message.INVALID_ARG_TYPE_UNARY);
+    @Fallback
+    protected Object invalidArgType(@SuppressWarnings("unused") Object operand) {
+        throw RError.error(getEncapsulatingSourceSection(), error);
     }
 
     protected static boolean isComplete(RAbstractVector cv) {
diff --git a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/unary/UnaryArithmeticReduceNode.java b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/unary/UnaryArithmeticReduceNode.java
index 2dc3bcdb4b82a23374457bf0bdaa717f6d26c198..bc46cceb0891e71932cfdcde91384bc64e36663b 100644
--- a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/unary/UnaryArithmeticReduceNode.java
+++ b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/unary/UnaryArithmeticReduceNode.java
@@ -73,33 +73,32 @@ public abstract class UnaryArithmeticReduceNode extends UnaryNode {
         return semantics.isNullInt();
     }
 
-    @SuppressWarnings("unused")
-    @Specialization(guards = "isNullInt")
-    protected int doInt(RNull operand, byte naRm) {
+    private void emptyWarning() {
         if (semantics.getEmptyWarning() != null) {
             RError.warning(semantics.emptyWarning);
         }
+    }
+
+    @SuppressWarnings("unused")
+    @Specialization(guards = "isNullInt")
+    protected int doInt(RNull operand, byte naRm) {
+        emptyWarning();
         return semantics.getIntStart();
     }
 
     @SuppressWarnings("unused")
     @Specialization(guards = "!isNullInt")
     protected double doDouble(RNull operand, byte naRm) {
-        if (semantics.getEmptyWarning() != null) {
-            RError.warning(semantics.emptyWarning);
-        }
+        emptyWarning();
         return semantics.getDoubleStart();
     }
 
     @Specialization
     protected int doInt(int operand, byte naRm) {
-        boolean profiledNaRm = naRmProfile.profile(naRm == RRuntime.LOGICAL_TRUE);
         na.enable(operand);
-        if (profiledNaRm) {
+        if (naRmProfile.profile(naRm == RRuntime.LOGICAL_TRUE)) {
             if (na.check(operand)) {
-                if (semantics.getEmptyWarning() != null) {
-                    RError.warning(semantics.emptyWarning);
-                }
+                emptyWarning();
                 return semantics.getIntStart();
             } else {
                 return operand;
@@ -111,13 +110,10 @@ public abstract class UnaryArithmeticReduceNode extends UnaryNode {
 
     @Specialization
     protected double doDouble(double operand, byte naRm) {
-        boolean profiledNaRm = naRmProfile.profile(naRm == RRuntime.LOGICAL_TRUE);
         na.enable(operand);
-        if (profiledNaRm) {
+        if (naRmProfile.profile(naRm == RRuntime.LOGICAL_TRUE)) {
             if (na.check(operand)) {
-                if (semantics.getEmptyWarning() != null) {
-                    RError.warning(semantics.emptyWarning);
-                }
+                emptyWarning();
                 return semantics.getIntStart();
             } else {
                 return operand;
@@ -129,13 +125,10 @@ public abstract class UnaryArithmeticReduceNode extends UnaryNode {
 
     @Specialization
     protected int doLogical(byte operand, byte naRm) {
-        boolean profiledNaRm = naRmProfile.profile(naRm == RRuntime.LOGICAL_TRUE);
         na.enable(operand);
-        if (profiledNaRm) {
+        if (naRmProfile.profile(naRm == RRuntime.LOGICAL_TRUE)) {
             if (na.check(operand)) {
-                if (semantics.getEmptyWarning() != null) {
-                    RError.warning(semantics.emptyWarning);
-                }
+                emptyWarning();
                 return semantics.getIntStart();
             } else {
                 return operand;
@@ -148,13 +141,10 @@ public abstract class UnaryArithmeticReduceNode extends UnaryNode {
     @Specialization
     protected RComplex doComplex(RComplex operand, byte naRm) {
         if (semantics.supportComplex) {
-            boolean profiledNaRm = naRmProfile.profile(naRm == RRuntime.LOGICAL_TRUE);
             na.enable(operand);
-            if (profiledNaRm) {
+            if (naRmProfile.profile(naRm == RRuntime.LOGICAL_TRUE)) {
                 if (na.check(operand)) {
-                    if (semantics.getEmptyWarning() != null) {
-                        RError.warning(semantics.emptyWarning);
-                    }
+                    emptyWarning();
                     return RRuntime.double2complex(semantics.getDoubleStart());
                 } else {
                     return operand;
@@ -170,13 +160,10 @@ public abstract class UnaryArithmeticReduceNode extends UnaryNode {
     @Specialization
     protected String doString(String operand, byte naRm) {
         if (semantics.supportString) {
-            boolean profiledNaRm = naRmProfile.profile(naRm == RRuntime.LOGICAL_TRUE);
             na.enable(operand);
-            if (profiledNaRm) {
+            if (naRmProfile.profile(naRm == RRuntime.LOGICAL_TRUE)) {
                 if (na.check(operand)) {
-                    if (semantics.getEmptyWarning() != null) {
-                        RError.warning(semantics.emptyWarning);
-                    }
+                    emptyWarning();
                     return semantics.getStringStart();
                 } else {
                     return operand;
diff --git a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/unary/UnaryNotNode.java b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/unary/UnaryNotNode.java
index 12bd94521df0e9df296403bb4f5e3570b78df6ed..48dec55dff2ed08ad05db19b061cea0f087582d3 100644
--- a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/unary/UnaryNotNode.java
+++ b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/unary/UnaryNotNode.java
@@ -23,6 +23,7 @@
 package com.oracle.truffle.r.nodes.unary;
 
 import com.oracle.truffle.api.dsl.*;
+import com.oracle.truffle.api.utilities.*;
 import com.oracle.truffle.r.nodes.builtin.*;
 import com.oracle.truffle.r.runtime.*;
 import com.oracle.truffle.r.runtime.data.*;
@@ -33,156 +34,140 @@ import com.oracle.truffle.r.runtime.ops.na.*;
 public abstract class UnaryNotNode extends RBuiltinNode {
 
     private final NACheck na = NACheck.create();
+    private final NAProfile naProfile = NAProfile.create();
+    private final ConditionProfile zeroLengthProfile = ConditionProfile.createBinaryProfile();
 
-    @Specialization
-    protected byte doLogical(byte operand) {
-        na.enable(operand);
-        if (na.check(operand)) {
-            return RRuntime.LOGICAL_NA;
-        }
-        return not(operand);
+    private static byte not(byte value) {
+        return (value == RRuntime.LOGICAL_TRUE ? RRuntime.LOGICAL_FALSE : RRuntime.LOGICAL_TRUE);
     }
 
-    @Specialization
-    protected byte doInt(int operand) {
-        na.enable(operand);
-        if (na.check(operand)) {
-            return RRuntime.LOGICAL_NA;
-        }
+    private static byte not(int operand) {
         return RRuntime.asLogical(operand == 0);
     }
 
-    @Specialization
-    protected byte doDouble(double operand) {
-        na.enable(operand);
-        if (na.check(operand)) {
-            return RRuntime.LOGICAL_NA;
-        }
+    private static byte not(double operand) {
         return RRuntime.asLogical(operand == 0);
     }
 
-    @Specialization
-    protected RRaw doRaw(RRaw operand) {
-        return RDataFactory.createRaw(performRaw(operand));
-    }
-
-    @SuppressWarnings("unused")
-    @Specialization
-    protected Object doNull(RNull operand) {
-        throw RError.error(getEncapsulatingSourceSection(), RError.Message.INVALID_ARG_TYPE);
-    }
-
-    private static byte performRaw(RRaw operand) {
+    private static byte notRaw(RRaw operand) {
         return (byte) (255 - operand.getValue());
     }
 
     @Specialization
-    protected RLogicalVector performLogicalVectorNot(@SuppressWarnings("unused") RFunction operand) {
-        throw RError.error(getEncapsulatingSourceSection(), RError.Message.INVALID_ARG_TYPE);
+    protected byte doLogical(byte operand) {
+        return naProfile.isNA(operand) ? RRuntime.LOGICAL_NA : not(operand);
     }
 
-    @Specialization(guards = "isZeroLength")
-    protected RLogicalVector performLogicalVectorNot(@SuppressWarnings("unused") RAbstractVector vector) {
-        return RDataFactory.createEmptyLogicalVector();
+    @Specialization
+    protected byte doInt(int operand) {
+        return naProfile.isNA(operand) ? RRuntime.LOGICAL_NA : not(operand);
     }
 
     @Specialization
-    protected RLogicalVector performLogicalVectorNot(@SuppressWarnings("unused") RAbstractStringVector vector) {
-        throw RError.error(getEncapsulatingSourceSection(), RError.Message.INVALID_ARG_TYPE);
+    protected byte doDouble(double operand) {
+        return naProfile.isNA(operand) ? RRuntime.LOGICAL_NA : not(operand);
     }
 
     @Specialization
-    protected RLogicalVector performLogicalVectorNot(@SuppressWarnings("unused") RList list) {
-        throw RError.error(getEncapsulatingSourceSection(), RError.Message.INVALID_ARG_TYPE);
+    protected RRaw doRaw(RRaw operand) {
+        return RDataFactory.createRaw(notRaw(operand));
     }
 
-    @Specialization(guards = "!isZeroLength")
+    @Specialization
     protected RLogicalVector doLogicalVector(RLogicalVector vector) {
-        return performLogicalVectorNot(vector);
-    }
-
-    @Specialization(guards = "!isZeroLength")
-    protected RLogicalVector doIntVector(RIntVector vector) {
-        return performAbstractIntVectorNot(vector);
-    }
-
-    @Specialization(guards = "!isZeroLength")
-    protected RLogicalVector doDoubleVector(RDoubleVector vector) {
-        return performAbstractDoubleVectorNot(vector);
-    }
-
-    @Specialization(guards = "!isZeroLength")
-    protected RLogicalVector doIntSequence(RIntSequence vector) {
-        return performAbstractIntVectorNot(vector);
-    }
-
-    @Specialization(guards = "!isZeroLength")
-    protected RLogicalVector doDoubleSequence(RDoubleSequence vector) {
-        return performAbstractDoubleVectorNot(vector);
-    }
-
-    @Specialization(guards = "!isZeroLength")
-    protected RRawVector doRawVector(RRawVector vector) {
-        return performRawVectorNot(vector);
-    }
-
-    private RLogicalVector performLogicalVectorNot(RLogicalVector vector) {
-        na.enable(vector);
         int length = vector.getLength();
-        byte[] result = new byte[length];
-        for (int i = 0; i < length; ++i) {
-            byte value = vector.getDataAt(i);
-            result[i] = doLogical(value);
+        byte[] result;
+        if (zeroLengthProfile.profile(length == 0)) {
+            result = RDataFactory.EMPTY_LOGICAL_ARRAY;
+        } else {
+            na.enable(vector);
+            result = new byte[length];
+            for (int i = 0; i < length; ++i) {
+                byte value = vector.getDataAt(i);
+                result[i] = na.check(value) ? RRuntime.LOGICAL_NA : not(value);
+            }
         }
         RLogicalVector resultVector = RDataFactory.createLogicalVector(result, na.neverSeenNA());
         resultVector.copyAttributesFrom(vector);
         return resultVector;
     }
 
-    private RLogicalVector performAbstractIntVectorNot(RAbstractIntVector vector) {
-        na.enable(vector);
+    @Specialization
+    protected RLogicalVector doIntVector(RAbstractIntVector vector) {
         int length = vector.getLength();
-        byte[] result = new byte[length];
-        for (int i = 0; i < length; ++i) {
-            int value = vector.getDataAt(i);
-            result[i] = doInt(value);
+        byte[] result;
+        if (zeroLengthProfile.profile(length == 0)) {
+            result = RDataFactory.EMPTY_LOGICAL_ARRAY;
+        } else {
+            na.enable(vector);
+            result = new byte[length];
+            for (int i = 0; i < length; ++i) {
+                int value = vector.getDataAt(i);
+                result[i] = na.check(value) ? RRuntime.LOGICAL_NA : not(value);
+            }
         }
         RLogicalVector resultVector = RDataFactory.createLogicalVector(result, na.neverSeenNA());
         resultVector.copyNamesDimsDimNamesFrom(vector, getSourceSection());
         return resultVector;
     }
 
-    private RLogicalVector performAbstractDoubleVectorNot(RAbstractDoubleVector vector) {
-        na.enable(vector);
+    @Specialization
+    protected RLogicalVector doDoubleVector(RAbstractDoubleVector vector) {
         int length = vector.getLength();
-        byte[] result = new byte[length];
-        for (int i = 0; i < length; ++i) {
-            double value = vector.getDataAt(i);
-            result[i] = doDouble(value);
+        byte[] result;
+        if (zeroLengthProfile.profile(length == 0)) {
+            result = RDataFactory.EMPTY_LOGICAL_ARRAY;
+        } else {
+            na.enable(vector);
+            result = new byte[length];
+            for (int i = 0; i < length; ++i) {
+                double value = vector.getDataAt(i);
+                result[i] = na.check(value) ? RRuntime.LOGICAL_NA : not(value);
+            }
         }
         RLogicalVector resultVector = RDataFactory.createLogicalVector(result, na.neverSeenNA());
-        resultVector.copyNamesFrom(vector);
+        resultVector.copyNamesDimsDimNamesFrom(vector, getSourceSection());
         return resultVector;
     }
 
-    private RRawVector performRawVectorNot(RRawVector vector) {
-        na.enable(vector);
+    @Specialization
+    protected RRawVector doRawVector(RRawVector vector) {
         int length = vector.getLength();
-        byte[] result = new byte[length];
-        for (int i = 0; i < length; ++i) {
-            RRaw value = vector.getDataAt(i);
-            result[i] = performRaw(value);
+        byte[] result;
+        if (zeroLengthProfile.profile(length == 0)) {
+            result = RDataFactory.EMPTY_RAW_ARRAY;
+        } else {
+            result = new byte[length];
+            for (int i = 0; i < length; ++i) {
+                result[i] = notRaw(vector.getDataAt(i));
+            }
         }
         RRawVector resultVector = RDataFactory.createRawVector(result);
         resultVector.copyAttributesFrom(vector);
         return resultVector;
     }
 
-    private static byte not(byte value) {
-        return (value == RRuntime.LOGICAL_TRUE ? RRuntime.LOGICAL_FALSE : RRuntime.LOGICAL_TRUE);
+    @Specialization(guards = {"isZeroLength"})
+    protected RLogicalVector doStringVector(@SuppressWarnings("unused") RAbstractStringVector vector) {
+        return RDataFactory.createEmptyLogicalVector();
+    }
+
+    @Specialization(guards = {"isZeroLength"})
+    protected RLogicalVector doComplexVector(@SuppressWarnings("unused") RAbstractComplexVector vector) {
+        return RDataFactory.createEmptyLogicalVector();
+    }
+
+    @Specialization(guards = {"isZeroLength"})
+    protected RLogicalVector doList(@SuppressWarnings("unused") RList list) {
+        return RDataFactory.createEmptyLogicalVector();
     }
 
     protected boolean isZeroLength(RAbstractVector vector) {
         return vector.getLength() == 0;
     }
+
+    @Fallback
+    protected Object invalidArgType(@SuppressWarnings("unused") Object operand) {
+        throw RError.error(getEncapsulatingSourceSection(), RError.Message.INVALID_ARG_TYPE);
+    }
 }
diff --git a/com.oracle.truffle.r.runtime.ffi/src/com/oracle/truffle/r/runtime/ffi/gnfi/GNFI_RFFIFactory.java b/com.oracle.truffle.r.runtime.ffi/src/com/oracle/truffle/r/runtime/ffi/gnfi/GNFI_RFFIFactory.java
index b574ed3fc36ba76e177bdf187226e88d9a67cc49..bc5608771aa4dd316533880c0257e2b16828da16 100644
--- a/com.oracle.truffle.r.runtime.ffi/src/com/oracle/truffle/r/runtime/ffi/gnfi/GNFI_RFFIFactory.java
+++ b/com.oracle.truffle.r.runtime.ffi/src/com/oracle/truffle/r/runtime/ffi/gnfi/GNFI_RFFIFactory.java
@@ -139,7 +139,7 @@ public class GNFI_RFFIFactory extends RFFIFactory implements RFFI, BaseRFFI {
                     return null;
                 } else {
                     // some other error
-                    throw ioex();
+                    throw ioex(null);
                 }
             } else {
                 return CString.create(resultBuf.address, length, false);
@@ -187,4 +187,13 @@ public class GNFI_RFFIFactory extends RFFIFactory implements RFFI, BaseRFFI {
         return 0;
     }
 
+    public void mkdir(String dir, int mode) throws IOException {
+        Utils.fail("mkdir not implemented");
+    }
+
+    public long strtol(String s, int base) throws IllegalArgumentException {
+        Utils.fail("strtol not implemented");
+        return 0;
+    }
+
 }
diff --git a/com.oracle.truffle.r.runtime.ffi/src/com/oracle/truffle/r/runtime/ffi/jnr/JNR_RFFIFactory.java b/com.oracle.truffle.r.runtime.ffi/src/com/oracle/truffle/r/runtime/ffi/jnr/JNR_RFFIFactory.java
index c706d3175516eada57c038384cf3c66d66c8dffa..6af93ea3926be667bee2cfb1fd44b78f13f63071 100644
--- a/com.oracle.truffle.r.runtime.ffi/src/com/oracle/truffle/r/runtime/ffi/jnr/JNR_RFFIFactory.java
+++ b/com.oracle.truffle.r.runtime.ffi/src/com/oracle/truffle/r/runtime/ffi/jnr/JNR_RFFIFactory.java
@@ -61,6 +61,8 @@ public class JNR_RFFIFactory extends RFFIFactory implements RFFI, BaseRFFI, RDer
         int getcwd(@Out byte[] path);
 
         long mkdtemp(@In @Out ByteBuffer template);
+
+        long strtol(@In String dir, @In String end, int base);
     }
 
     private static class LibCXProvider {
@@ -127,7 +129,7 @@ public class JNR_RFFIFactory extends RFFIFactory implements RFFI, BaseRFFI, RDer
                 // not a link
             } else {
                 // some other error
-                throw ioex();
+                throw ioex(Errno.valueOf(n).description());
             }
         }
         return s;
@@ -143,6 +145,25 @@ public class JNR_RFFIFactory extends RFFIFactory implements RFFI, BaseRFFI, RDer
         }
     }
 
+    public void mkdir(String dir, int mode) throws IOException {
+        try {
+            posix().mkdir(dir, mode);
+        } catch (RuntimeException ex) {
+            throw ioex(Errno.valueOf(posix().errno()).description());
+        }
+    }
+
+    public long strtol(String s, int base) throws IllegalArgumentException {
+        posix().errno(0);
+        long result = libcx().strtol(s, null, base);
+        int e = posix().errno();
+        if (e != 0) {
+            throw new IllegalArgumentException(Errno.valueOf(e).description());
+        } else {
+            return result;
+        }
+    }
+
     public Object dlopen(String path, boolean local, boolean now) {
         int flags = (local ? com.kenai.jffi.Library.LOCAL : com.kenai.jffi.Library.GLOBAL) | (now ? com.kenai.jffi.Library.NOW : com.kenai.jffi.Library.LAZY);
         return com.kenai.jffi.Library.getCachedInstance(path, flags);
@@ -631,4 +652,5 @@ public class JNR_RFFIFactory extends RFFIFactory implements RFFI, BaseRFFI, RDer
     public int uncompress(byte[] dest, long[] destlen, byte[] source) {
         return zip().uncompress(dest, destlen, source, source.length);
     }
+
 }
diff --git a/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/data/RDataFactory.java b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/data/RDataFactory.java
index c5ea07be92d6dff51336e2e7854a6a1dc10c2c5f..d7ae5ec067ca56b881ee81d3ea2f997a20ae5a35 100644
--- a/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/data/RDataFactory.java
+++ b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/data/RDataFactory.java
@@ -37,6 +37,10 @@ public final class RDataFactory {
     private static final RStringVector EMPTY_STRING_VECTOR = createStringVector(0);
     private static final RComplexVector EMPTY_COMPLEX_VECTOR = createComplexVector(0);
     private static final RRawVector EMPTY_RAW_VECTOR = createRawVector(0);
+
+    public static final byte[] EMPTY_RAW_ARRAY = new byte[0];
+    public static final byte[] EMPTY_LOGICAL_ARRAY = new byte[0];
+
     public static final boolean INCOMPLETE_VECTOR = false;
     public static final boolean COMPLETE_VECTOR = true;
 
diff --git a/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/ffi/BaseRFFI.java b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/ffi/BaseRFFI.java
index 01d255ec9f3bda6a3576941602261859e71f019a..9773ffb566b7d0310194ddd3f6346172a4607793 100644
--- a/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/ffi/BaseRFFI.java
+++ b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/ffi/BaseRFFI.java
@@ -44,6 +44,11 @@ public interface BaseRFFI {
      */
     int setwd(String dir);
 
+    /**
+     * Create directory with given mode. Exception is thrown omn error.
+     */
+    void mkdir(String dir, int mode) throws IOException;
+
     /**
      * Try to convert a symbolic link to it's target.
      *
@@ -94,4 +99,9 @@ public interface BaseRFFI {
      */
     int uncompress(byte[] dest, long[] destlen, byte[] source);
 
+    /**
+     * Convert string to long.
+     */
+    long strtol(String s, int base) throws IllegalArgumentException;
+
 }
diff --git a/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/ffi/RFFIFactory.java b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/ffi/RFFIFactory.java
index be62aad8b1c6b78fde58a9d57bf678535eed5fd7..260708527272070f6ad9222020015118fde0ed41 100644
--- a/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/ffi/RFFIFactory.java
+++ b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/ffi/RFFIFactory.java
@@ -82,8 +82,8 @@ public abstract class RFFIFactory {
     }
 
     @TruffleBoundary
-    protected static IOException ioex() throws IOException {
-        throw new IOException();
+    protected static IOException ioex(String errMsg) throws IOException {
+        throw new IOException(errMsg);
     }
 
 }
diff --git a/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/ExpectedTestOutput.test b/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/ExpectedTestOutput.test
index 6f9e43f33559d184b61fcb525ed04a411f81f8a3..4c1ccfdf8c12d6f6bf890a50e93c33bec3edaa71 100644
--- a/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/ExpectedTestOutput.test
+++ b/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/ExpectedTestOutput.test
@@ -1407,6 +1407,14 @@ complex(0)
 #{ -c((1+0i)/0,2) }
 [1] NaN+NaNi  -2+  0i
 
+##com.oracle.truffle.r.test.simple.TestSimpleArithmetic.testUnaryMinusDimensions
+#{ xx <- double(0); dim(xx) <- c(0,0); dim(-xx) }
+[1] 0 0
+
+##com.oracle.truffle.r.test.simple.TestSimpleArithmetic.testUnaryMinusDimensions
+#{ xx <- double(1); dim(xx) <- c(1,1); dim(-xx) }
+[1] 1 1
+
 ##com.oracle.truffle.r.test.simple.TestSimpleArithmetic.testUnaryMinusErrors
 #{ f <- function(z) { -z } ; f(1:3) ; f("hello") }
 Error in -z : invalid argument to unary operator
@@ -1435,6 +1443,14 @@ Error in -z : invalid argument to unary operator
 #{ !TRUE }
 [1] FALSE
 
+##com.oracle.truffle.r.test.simple.TestSimpleArithmetic.testUnaryNotDimensions
+#{ xx <- double(0); dim(xx) <- c(0,0); dim(!xx) }
+[1] 0 0
+
+##com.oracle.truffle.r.test.simple.TestSimpleArithmetic.testUnaryNotDimensions
+#{ xx <- double(1); dim(xx) <- c(1,1); dim(!xx) }
+[1] 1 1
+
 ##com.oracle.truffle.r.test.simple.TestSimpleArithmetic.testUnaryNotError
 #{ l <- c("hello", "hi") ; !l }
 Error in !l : invalid argument type
@@ -6089,6 +6105,12 @@ hi 1 2 3 hello
 ##com.oracle.truffle.r.test.simple.TestSimpleBuiltins.testCat
 #{ cat("hi",1[2],"hello",sep="-") }
 hi-NA-hello
+##com.oracle.truffle.r.test.simple.TestSimpleBuiltins.testCat
+#{ cat("hi",1[2],"hello",sep="-\n") }
+hi-
+NA-
+hello
+
 ##com.oracle.truffle.r.test.simple.TestSimpleBuiltins.testCat
 #{ cat() }
 
@@ -6098,6 +6120,10 @@ hi-NA-hello
 ##com.oracle.truffle.r.test.simple.TestSimpleBuiltins.testCat
 #{ cat(1, "a") }
 1 a
+##com.oracle.truffle.r.test.simple.TestSimpleBuiltins.testCat
+#{ cat(1, sep="\n") }
+1
+
 ##com.oracle.truffle.r.test.simple.TestSimpleBuiltins.testCat
 #{ cat(1,2,3) }
 1 2 3
@@ -6156,6 +6182,21 @@ hello
 ##com.oracle.truffle.r.test.simple.TestSimpleBuiltins.testCat
 #{ m <- matrix(as.character(1:6), nrow=2) ; cat(m) }
 1 2 3 4 5 6
+##com.oracle.truffle.r.test.simple.TestSimpleBuiltins.testCatVarargs
+#{ f <- function(...) {cat(...,sep="-")}; f("a") }
+a
+##com.oracle.truffle.r.test.simple.TestSimpleBuiltins.testCatVarargs
+#{ f <- function(...) {cat(...,sep="-")}; f("a", "b") }
+a-b
+##com.oracle.truffle.r.test.simple.TestSimpleBuiltins.testCatVarargs
+#{ f <- function(...) {cat(...,sep="-\n")}; f("a") }
+a
+
+##com.oracle.truffle.r.test.simple.TestSimpleBuiltins.testCatVarargs
+#{ f <- function(...) {cat(...,sep="-\n")}; f("a", "b") }
+a-
+b
+
 ##com.oracle.truffle.r.test.simple.TestSimpleBuiltins.testCbind
 #{ cbind() }
 NULL
@@ -8532,6 +8573,10 @@ NULL
 #{ inherits(new.env(), "try-error") }
 [1] FALSE
 
+##com.oracle.truffle.r.test.simple.TestSimpleBuiltins.testInherits
+#{ inherits(textConnection("abc"), "connection") }
+[1] TRUE
+
 ##com.oracle.truffle.r.test.simple.TestSimpleBuiltins.testInherits
 #{ x<-data.frame(c(1,2)); inherits(x, "data.frame") }
 [1] TRUE
diff --git a/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/all/AllTests.java b/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/all/AllTests.java
index c50e14f06b1da06a2898cd234833034c791a97a9..d0877e00e11531382d33c697fb23ffc48ada1ce3 100644
--- a/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/all/AllTests.java
+++ b/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/all/AllTests.java
@@ -1733,6 +1733,16 @@ public class AllTests extends TestBase {
         assertEval("{ -c((1+0i)/0,2) }");
     }
 
+    @Test
+    public void TestSimpleArithmetic_testUnaryMinusDimensions_82d8cc2dfa20802f3af03d30533599c1() {
+        assertEval("{ xx <- double(0); dim(xx) <- c(0,0); dim(-xx) }");
+    }
+
+    @Test
+    public void TestSimpleArithmetic_testUnaryMinusDimensions_1c0bc1dd2399b5dd2298ffe8d8da94c2() {
+        assertEval("{ xx <- double(1); dim(xx) <- c(1,1); dim(-xx) }");
+    }
+
     @Test
     public void TestSimpleArithmetic_testUnaryMinusErrors_c1f5e118009944a5b67f947745697a4a() {
         assertEvalError("{ z <- \"hello\" ; -z }");
@@ -1768,6 +1778,16 @@ public class AllTests extends TestBase {
         assertEval("{ !NA }");
     }
 
+    @Test
+    public void TestSimpleArithmetic_testUnaryNotDimensions_c06858978ee19736bc28f17e7c3acf08() {
+        assertEval("{ xx <- double(0); dim(xx) <- c(0,0); dim(!xx) }");
+    }
+
+    @Test
+    public void TestSimpleArithmetic_testUnaryNotDimensions_e16c9de9476e28643ba613022602d2a6() {
+        assertEval("{ xx <- double(1); dim(xx) <- c(1,1); dim(!xx) }");
+    }
+
     @Test
     public void TestSimpleArithmetic_testUnaryNotError_e1de893845dc88297503728fe5d2e03c() {
         assertEval("{ x<-1:4; dim(x)<-c(2, 2); names(x)<-101:104; attr(x, \"dimnames\")<-list(c(\"201\", \"202\"), c(\"203\", \"204\")); attr(x, \"foo\")<-\"foo\"; y<-!x; attributes(y) }");
@@ -5683,6 +5703,11 @@ public class AllTests extends TestBase {
         assertEvalNoNL("{ cat(1) }");
     }
 
+    @Test
+    public void TestSimpleBuiltins_testCat_5cd9f21c97025b5427f8244d0c0e0ffc() {
+        assertEvalNoNL("{ cat(1, sep=\"\\n\") }");
+    }
+
     @Test
     public void TestSimpleBuiltins_testCat_f48953c23109705840adb64bc147151b() {
         assertEvalNoNL("{ cat(1,2,3) }");
@@ -5788,6 +5813,11 @@ public class AllTests extends TestBase {
         assertEvalNoNL("{ cat(\"hi\",1[2],\"hello\",sep=\"-\") }");
     }
 
+    @Test
+    public void TestSimpleBuiltins_testCat_91de7df676b06ad665ce3584e334842c() {
+        assertEvalNoNL("{ cat(\"hi\",1[2],\"hello\",sep=\"-\\n\") }");
+    }
+
     @Test
     public void TestSimpleBuiltins_testCat_1dcd33ce696ea60d54dd157e9d0dd76f() {
         assertEvalNoNL("{ m <- matrix(as.character(1:6), nrow=2) ; cat(m) }");
@@ -5813,6 +5843,26 @@ public class AllTests extends TestBase {
         assertEvalNoNL("{ cat(\"hi\",integer(0),\"hello\",sep=\"-\") }");
     }
 
+    @Test
+    public void TestSimpleBuiltins_testCatVarargs_ff51d78a6902080ce5f8721aa9bd9932() {
+        assertEvalNoOutput("{ f <- function(...) {cat(...,sep=\"-\")}; f(\"a\") }");
+    }
+
+    @Test
+    public void TestSimpleBuiltins_testCatVarargs_a217c0f15c1bc137c95929aaed1c51f2() {
+        assertEvalNoOutput("{ f <- function(...) {cat(...,sep=\"-\\n\")}; f(\"a\") }");
+    }
+
+    @Test
+    public void TestSimpleBuiltins_testCatVarargs_ca16199a5bf10ef8a2fccd05debcaf73() {
+        assertEvalNoOutput("{ f <- function(...) {cat(...,sep=\"-\")}; f(\"a\", \"b\") }");
+    }
+
+    @Test
+    public void TestSimpleBuiltins_testCatVarargs_782dd61fabc4402b2636903c37f05fe6() {
+        assertEvalNoOutput("{ f <- function(...) {cat(...,sep=\"-\\n\")}; f(\"a\", \"b\") }");
+    }
+
     @Test
     public void TestSimpleBuiltins_testCbind_b6d50b783340cfd840b5d0d1c478e85a() {
         assertEval("{ cbind() }");
@@ -8453,6 +8503,11 @@ public class AllTests extends TestBase {
         assertEval("{ x<-factor(\"a\", \"b\", \"a\"); inherits(x, \"factor\") }");
     }
 
+    @Test
+    public void TestSimpleBuiltins_testInherits_34ff95edf55241d7710a1123747655e8() {
+        assertEval("{ inherits(textConnection(\"abc\"), \"connection\") }");
+    }
+
     @Test
     public void TestSimpleBuiltins_testInheritsIgnore_d0dc6389c924878311546ba61d753a22() {
         assertEval("{x <- 10;class(x) <- c(\"a\", \"b\");inherits(x, 2, c(TRUE)) ;}");
diff --git a/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/simple/TestSimpleArithmetic.java b/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/simple/TestSimpleArithmetic.java
index 46c3b442bdf322e1f7dd01c4b2a2551da2b3dcc3..a023c8f078d86df0fed71ee225e5b2762820112d 100644
--- a/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/simple/TestSimpleArithmetic.java
+++ b/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/simple/TestSimpleArithmetic.java
@@ -374,6 +374,12 @@ public class TestSimpleArithmetic extends TestBase {
         assertEval("{ x<-1:4; dim(x)<-c(2, 2); names(x)<-101:104; attr(x, \"dimnames\")<-list(201:202, 203:204); attr(x, \"foo\")<-\"foo\"; y<-!x; attributes(y) }");
     }
 
+    @Test
+    public void testUnaryNotDimensions() {
+        assertEval("{ xx <- double(0); dim(xx) <- c(0,0); dim(!xx) }");
+        assertEval("{ xx <- double(1); dim(xx) <- c(1,1); dim(!xx) }");
+    }
+
     @Test
     public void testUnaryMinus() {
         assertEval("{ -3 }");
@@ -425,6 +431,12 @@ public class TestSimpleArithmetic extends TestBase {
         assertEvalError("{ f <- function(z) { -z } ; f(1:3) ; f(\"hello\") }");
     }
 
+    @Test
+    public void testUnaryMinusDimensions() {
+        assertEval("{ xx <- double(0); dim(xx) <- c(0,0); dim(-xx) }");
+        assertEval("{ xx <- double(1); dim(xx) <- c(1,1); dim(-xx) }");
+    }
+
     @Test
     public void testMatrices() {
         assertEval("{ m <- matrix(1:6, nrow=2, ncol=3, byrow=TRUE) ; m-1 }");
diff --git a/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/simple/TestSimpleBuiltins.java b/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/simple/TestSimpleBuiltins.java
index 0d91359ab0ee78284e322286a96b087bc622fa5e..5dd75c552a11ce6c653d2c4f29b6e33b42e8b4ba 100644
--- a/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/simple/TestSimpleBuiltins.java
+++ b/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/simple/TestSimpleBuiltins.java
@@ -965,6 +965,7 @@ public class TestSimpleBuiltins extends TestBase {
     public void testCat() {
         assertEvalNoOutput("{ cat() }");
         assertEvalNoNL("{ cat(1) }");
+        assertEvalNoNL("{ cat(1, sep=\"\\n\") }");
         assertEvalNoNL("{ cat(1,2,3) }");
         assertEvalNoNL("{ cat(\"a\") }");
         assertEvalNoNL("{ cat(\"a\", \"b\") }");
@@ -986,11 +987,20 @@ public class TestSimpleBuiltins extends TestBase {
         assertEvalNoNL("{ cat(c(1L, 2L, 3L)) }");
         assertEvalNoNL("{ cat(1,2,sep=\".\") }");
         assertEvalNoNL("{ cat(\"hi\",1[2],\"hello\",sep=\"-\") }");
+        assertEvalNoNL("{ cat(\"hi\",1[2],\"hello\",sep=\"-\\n\") }");
         assertEvalNoNL("{ m <- matrix(as.character(1:6), nrow=2) ; cat(m) }");
         assertEvalNoNL("{ cat(sep=\" \", \"hello\") }");
         assertEval("{ cat(rep(NA, 8), \"Hey\",\"Hey\",\"Goodbye\",\"\\n\") }");
     }
 
+    @Test
+    public void testCatVarargs() {
+        assertEvalNoOutput("{ f <- function(...) {cat(...,sep=\"-\")}; f(\"a\") }");
+        assertEvalNoOutput("{ f <- function(...) {cat(...,sep=\"-\\n\")}; f(\"a\") }");
+        assertEvalNoOutput("{ f <- function(...) {cat(...,sep=\"-\")}; f(\"a\", \"b\") }");
+        assertEvalNoOutput("{ f <- function(...) {cat(...,sep=\"-\\n\")}; f(\"a\", \"b\") }");
+    }
+
     @Test
     @Ignore
     public void testCatIgnore() {
@@ -3297,6 +3307,7 @@ public class TestSimpleBuiltins extends TestBase {
 
         assertEval("{ x<-data.frame(c(1,2)); inherits(x, \"data.frame\") }");
         assertEval("{ x<-factor(\"a\", \"b\", \"a\"); inherits(x, \"factor\") }");
+        assertEval("{ inherits(textConnection(\"abc\"), \"connection\") }");
     }
 
     @Test