diff --git a/com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/fastrGrid/graphics/CPar.java b/com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/fastrGrid/graphics/CPar.java
index 4f520f1f2ab9159d8f48ae00fd8f13fd00f48263..f076d1a5e64fc162513b8369fe2d4d50108ec9d0 100644
--- a/com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/fastrGrid/graphics/CPar.java
+++ b/com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/fastrGrid/graphics/CPar.java
@@ -31,6 +31,7 @@ import com.oracle.truffle.r.library.fastrGrid.device.DrawingContext;
 import com.oracle.truffle.r.library.fastrGrid.device.GridDevice;
 import com.oracle.truffle.r.library.fastrGrid.grDevices.OpenDefaultDevice;
 import com.oracle.truffle.r.nodes.builtin.RExternalBuiltinNode;
+import com.oracle.truffle.r.runtime.FastROptions;
 import com.oracle.truffle.r.runtime.RError;
 import com.oracle.truffle.r.runtime.RError.Message;
 import com.oracle.truffle.r.runtime.RRuntime;
@@ -114,7 +115,11 @@ public final class CPar extends RExternalBuiltinNode {
                 // TODO:
                 return RDataFactory.createLogicalVectorFromScalar(false);
             default:
-                throw RError.nyi(RError.NO_CALLER, "C_Par parameter '" + name + "'");
+                if (!FastROptions.IgnoreGraphicsCalls.getBooleanValue()) {
+                    throw RError.nyi(RError.NO_CALLER, "C_Par parameter '" + name + "'");
+                } else {
+                    return RNull.instance;
+                }
         }
     }
 
diff --git a/com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/fastrGrid/graphics/R/fastrGraphics.R b/com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/fastrGrid/graphics/R/fastrGraphics.R
index 2ffbef80c874914e8e0457462f1055a3f1d6ed33..f1d333aa7dfd2e9030bf4bc2c8136ee0b2e0992e 100644
--- a/com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/fastrGrid/graphics/R/fastrGraphics.R
+++ b/com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/fastrGrid/graphics/R/fastrGraphics.R
@@ -25,24 +25,29 @@
 # prints a warning message instructing the user to use grid/lattice/ggplot2 instead
 
 eval(expression({
-    graphicsWarning <- function(name) {
-    	# lookup original function and fetch signature
-    	fun <- tryCatch(get(name, environment()), error=function(x) NULL)
-    	if(!is.null(fun)) {
-    	    sig <- formals(fun)
-    	} else {
-    	    sig <- NULL
-    	}
-    	
-        replacementFun <- function(...) {
-            warning(paste0(name, " not supported.", " Note: FastR does not support graphics package and most of its functions. Please use grid package or grid based packages like lattice instead."))
-            NULL
-        }
+    if (.fastr.option('IgnoreGraphicsCalls')) {
+        # we force the arguments to be evaluated, but otherwise do nothing
+        graphicsWarning <- function(name) function(...) { list(...); invisible(NULL); }
+    } else {
+        graphicsWarning <- function(name) {
+            # lookup original function and fetch signature
+            fun <- tryCatch(get(name, environment()), error=function(x) NULL)
+            if(!is.null(fun)) {
+                sig <- formals(fun)
+            } else {
+                sig <- NULL
+            }
+
+            replacementFun <- function(...) {
+                warning(paste0(name, " not supported.", " Note: FastR does not support graphics package and most of its functions. Please use grid package or grid based packages like lattice instead."))
+                NULL
+            }
 
-		if(!is.null(sig)) {
-        	formals(replacementFun) <- sig
+            if(!is.null(sig)) {
+                formals(replacementFun) <- sig
+            }
+            return(replacementFun)
         }
-        return(replacementFun)
     }
 
     plot.default <- function (x, y = NULL, type = "p", xlim = NULL, ylim = NULL,
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 bbce2245242a70a7436c27bae48116004676e96c..349a1f8e3be3f65f7012aa410ef9b8badbfc2a7d 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
@@ -66,6 +66,7 @@ import com.oracle.truffle.r.runtime.builtins.RBuiltin;
 import com.oracle.truffle.r.runtime.data.RDataFactory;
 import com.oracle.truffle.r.runtime.data.RLanguage;
 import com.oracle.truffle.r.runtime.data.RNull;
+import com.oracle.truffle.r.runtime.data.RPairList;
 import com.oracle.truffle.r.runtime.data.RSharingAttributeStorage;
 import com.oracle.truffle.r.runtime.data.RStringVector;
 import com.oracle.truffle.r.runtime.data.RSymbol;
@@ -260,6 +261,12 @@ public abstract class AsVector extends RBuiltinNode.Arg2 {
                 return RNull.instance;
             }
 
+            @Specialization
+            @TruffleBoundary
+            protected Object doPairList(RPairList list) {
+                return list.copy();
+            }
+
             @Fallback
             protected Object castPairlist(Object x) {
                 throw RInternalError.unimplemented("non-list casts to pairlist for " + x.getClass().getSimpleName());
diff --git a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/BasePackage.java b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/BasePackage.java
index de74bbaa12896b6f15044afdb7da4d79709bf5af..438bccd17c05f57b5621b8b478ef68ff75fe6749 100644
--- a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/BasePackage.java
+++ b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/BasePackage.java
@@ -109,6 +109,7 @@ import com.oracle.truffle.r.nodes.builtin.fastr.FastRInterop;
 import com.oracle.truffle.r.nodes.builtin.fastr.FastRInteropFactory;
 import com.oracle.truffle.r.nodes.builtin.fastr.FastRLibPaths;
 import com.oracle.truffle.r.nodes.builtin.fastr.FastRLibPathsNodeGen;
+import com.oracle.truffle.r.nodes.builtin.fastr.FastROptionBuiltin;
 import com.oracle.truffle.r.nodes.builtin.fastr.FastRPkgSource;
 import com.oracle.truffle.r.nodes.builtin.fastr.FastRPkgSourceNodeGen;
 import com.oracle.truffle.r.nodes.builtin.fastr.FastRRefCountInfo;
@@ -435,6 +436,7 @@ public class BasePackage extends RBuiltinPackage {
         add(FastRSetBreakpoint.class, FastRSetBreakpointNodeGen::create);
         add(FastRHelp.class, FastRHelpNodeGen::create);
         add(FastRIdentity.class, FastRIdentityNodeGen::create);
+        add(FastROptionBuiltin.class, FastROptionBuiltin::create);
         add(FastRTry.class, FastRTryNodeGen::create);
         add(FastRInspect.class, FastRInspectNodeGen::create);
         add(FastRInterop.Eval.class, FastRInteropFactory.EvalNodeGen::create);
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 cee07fbd4bbce686c77f167e96131042d7bf0c49..c1002705f1527f1de76d9b2759a3f7fd9b165218 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
@@ -50,9 +50,11 @@ import com.oracle.truffle.r.runtime.builtins.RBuiltin;
 import com.oracle.truffle.r.runtime.conn.RConnection;
 import com.oracle.truffle.r.runtime.context.RContext;
 import com.oracle.truffle.r.runtime.data.RDataFactory;
+import com.oracle.truffle.r.runtime.data.REmpty;
 import com.oracle.truffle.r.runtime.data.RExpression;
 import com.oracle.truffle.r.runtime.data.RLanguage;
 import com.oracle.truffle.r.runtime.data.RList;
+import com.oracle.truffle.r.runtime.data.RMissing;
 import com.oracle.truffle.r.runtime.data.RNull;
 import com.oracle.truffle.r.runtime.data.RStringVector;
 import com.oracle.truffle.r.runtime.data.RTypedValue;
@@ -112,6 +114,15 @@ public abstract class Cat extends RBuiltinNode.Arg6 {
 
     @TruffleBoundary
     private RNull output(RList args, int file, RAbstractStringVector sepVec, int fillWidth, RAbstractStringVector labels, @SuppressWarnings("unused") boolean append) {
+        for (int i = 0; i < args.getLength(); i++) {
+            Object obj = args.getDataAt(i);
+            if (obj == REmpty.instance) {
+                // Note: we cannot easily get the name of the original argument, so we use a
+                // different error message than GNUR.
+                throw error(Message.MISSING_INVALID);
+            }
+        }
+
         RConnection conn = RConnection.fromIndex(file);
         boolean filling = fillWidth > 0;
         ensureToString();
@@ -128,7 +139,7 @@ public abstract class Cat extends RBuiltinNode.Arg6 {
                 for (int j = 0; j < stringVec.getLength(); j++) {
                     stringVecs.add(stringVec.getDataAt(j));
                 }
-            } else if (obj instanceof RNull) {
+            } else if (obj == RNull.instance || obj == RMissing.instance) {
                 continue;
             } else if (obj instanceof String) {
                 stringVecs.add((String) obj);
diff --git a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/OptionsFunctions.java b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/OptionsFunctions.java
index 43d5493d06ba6c9e958597448d8b78aad39c9420..747c673fc0db715916387ac6b7eb72c2eec6d0ea 100644
--- a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/OptionsFunctions.java
+++ b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/OptionsFunctions.java
@@ -28,7 +28,12 @@ import static com.oracle.truffle.r.runtime.builtins.RBehavior.MODIFIES_STATE;
 import static com.oracle.truffle.r.runtime.builtins.RBehavior.READS_STATE;
 import static com.oracle.truffle.r.runtime.builtins.RBuiltinKind.INTERNAL;
 
+import java.text.Collator;
+import java.util.Arrays;
+import java.util.Comparator;
+import java.util.Locale;
 import java.util.Map;
+import java.util.Map.Entry;
 import java.util.Set;
 
 import com.oracle.truffle.api.CompilerDirectives.TruffleBoundary;
@@ -41,6 +46,7 @@ import com.oracle.truffle.r.nodes.function.visibility.SetVisibilityNode;
 import com.oracle.truffle.r.runtime.ArgumentsSignature;
 import com.oracle.truffle.r.runtime.RError;
 import com.oracle.truffle.r.runtime.RError.Message;
+import com.oracle.truffle.r.runtime.RLocale;
 import com.oracle.truffle.r.runtime.ROptions;
 import com.oracle.truffle.r.runtime.ROptions.OptionsException;
 import com.oracle.truffle.r.runtime.builtins.RBuiltin;
@@ -72,8 +78,22 @@ public class OptionsFunctions {
             Set<Map.Entry<String, Object>> optionSettings = RContext.getInstance().stateROptions.getValues();
             Object[] data = new Object[optionSettings.size()];
             String[] names = new String[data.length];
+
+            @SuppressWarnings({"unchecked", "rawtypes"})
+            Map.Entry<String, Object>[] entries = optionSettings.toArray(new Map.Entry[optionSettings.size()]);
+            Locale locale = RContext.getInstance().stateRLocale.getLocale(RLocale.COLLATE);
+            Collator collator = locale == Locale.ROOT || locale == null ? null : RLocale.getOrderCollator(locale);
+            Arrays.sort(entries, new Comparator<Map.Entry<String, Object>>() {
+                @Override
+                public int compare(Map.Entry<String, Object> o1, Map.Entry<String, Object> o2) {
+                    String k1 = o1.getKey();
+                    String k2 = o2.getKey();
+                    return collator == null ? k1.compareTo(k2) : collator.compare(k1, k2);
+                }
+            });
+
             int i = 0;
-            for (Map.Entry<String, Object> entry : optionSettings) {
+            for (Map.Entry<String, Object> entry : entries) {
                 names[i] = entry.getKey();
                 data[i] = entry.getValue();
                 i++;
@@ -119,7 +139,7 @@ public class OptionsFunctions {
             for (int i = 0; i < values.length; i++) {
                 String argName = signature.getName(i);
                 Object value = values[i];
-                if (argNameNull.profile(argName == null)) {
+                if (argNameNull.profile(argName == null || value instanceof RList)) {
                     // getting
                     String optionName = null;
                     if (value instanceof RStringVector) {
@@ -146,6 +166,8 @@ public class OptionsFunctions {
                             listNames[j] = name;
                             options.setValue(name, list.getDataAtAsObject(j));
                         }
+                        // any settings means result is invisible
+                        visible = false;
                         // if this is the only argument, no need to copy, can just return
                         if (values.length == 1) {
                             data = listData;
diff --git a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/Order.java b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/Order.java
index a3aa04791edfcdee8f32877b9552a29d4a481f69..c188ea4ce08a296a3bf0c5e8b7750583ecf8c6ea 100644
--- a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/Order.java
+++ b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/Order.java
@@ -20,8 +20,6 @@ import static com.oracle.truffle.r.runtime.builtins.RBuiltinKind.INTERNAL;
 
 import java.text.CollationKey;
 import java.text.Collator;
-import java.text.ParseException;
-import java.text.RuleBasedCollator;
 import java.util.Locale;
 
 import com.oracle.truffle.api.CompilerDirectives;
@@ -40,7 +38,6 @@ import com.oracle.truffle.r.nodes.builtin.base.SortFunctions.RadixSort;
 import com.oracle.truffle.r.nodes.unary.CastToVectorNode;
 import com.oracle.truffle.r.nodes.unary.CastToVectorNodeGen;
 import com.oracle.truffle.r.runtime.RError;
-import com.oracle.truffle.r.runtime.RInternalError;
 import com.oracle.truffle.r.runtime.RLocale;
 import com.oracle.truffle.r.runtime.RRuntime;
 import com.oracle.truffle.r.runtime.RType;
@@ -566,14 +563,7 @@ public abstract class Order extends RPrecedenceBuiltinNode {
                 }
             } else {
                 int length = dv.getLength();
-                Collator baseCollator = Collator.getInstance(locale);
-                String rules = ((RuleBasedCollator) baseCollator).getRules();
-                Collator collator;
-                try {
-                    collator = new RuleBasedCollator(rules.replaceAll("<'\u005f'", "<' '<'\u005f'"));
-                } catch (ParseException e) {
-                    throw RInternalError.shouldNotReachHere(e);
-                }
+                Collator collator = RLocale.getOrderCollator(locale);
                 CollationKey[] entries = new CollationKey[length];
                 for (int i = 0; i < length; i++) {
                     entries[i] = collator.getCollationKey(dv.getDataAt(i));
diff --git a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/fastr/FastROptionBuiltin.java b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/fastr/FastROptionBuiltin.java
new file mode 100644
index 0000000000000000000000000000000000000000..a5b8a799baf880c2f5445a08ed02b72c11af395b
--- /dev/null
+++ b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/fastr/FastROptionBuiltin.java
@@ -0,0 +1,66 @@
+/*
+ * Copyright (c) 2015, 2017, 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.fastr;
+
+import static com.oracle.truffle.r.runtime.RVisibility.OFF;
+import static com.oracle.truffle.r.runtime.RVisibility.ON;
+import static com.oracle.truffle.r.runtime.builtins.RBehavior.COMPLEX;
+import static com.oracle.truffle.r.runtime.builtins.RBuiltinKind.PRIMITIVE;
+
+import com.oracle.truffle.api.CompilerDirectives.TruffleBoundary;
+import com.oracle.truffle.api.dsl.Specialization;
+import com.oracle.truffle.r.nodes.builtin.RBuiltinNode;
+import com.oracle.truffle.r.runtime.FastROptions;
+import com.oracle.truffle.r.runtime.RRuntime;
+import com.oracle.truffle.r.runtime.builtins.RBuiltin;
+import com.oracle.truffle.r.runtime.data.RMissing;
+import com.oracle.truffle.r.runtime.data.RNull;
+import com.oracle.truffle.r.runtime.data.model.RAbstractStringVector;
+
+/**
+ * Allows to read {@link FastROptions} from (e.g. internal) R code.
+ */
+@RBuiltin(name = ".fastr.option", visibility = ON, kind = PRIMITIVE, parameterNames = {"name"}, behavior = COMPLEX)
+public abstract class FastROptionBuiltin extends RBuiltinNode.Arg1 {
+
+    static {
+        Casts casts = new Casts(FastROptionBuiltin.class);
+        casts.arg("name").asStringVector().findFirst();
+    }
+
+    @Specialization
+    @TruffleBoundary
+    protected Object getOption(String name) {
+        FastROptions opt = null;
+        try {
+            opt = Enum.valueOf(FastROptions.class, name);
+        } catch (IllegalArgumentException e) {
+            return RNull.instance;
+        }
+        return opt.isBoolean() ? RRuntime.asLogical(opt.getBooleanValue()) : opt.getStringValue();
+    }
+
+    public static FastROptionBuiltin create() {
+        return FastROptionBuiltinNodeGen.create();
+    }
+}
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 ff55cf9f8b2ea74de50f2a1f1f5752d537e31fd9..0541c5523b79038b7dbd6c335f7e281640464bd9 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
@@ -32,18 +32,17 @@ import com.oracle.truffle.api.frame.VirtualFrame;
 import com.oracle.truffle.api.interop.TruffleObject;
 import com.oracle.truffle.api.profiles.BranchProfile;
 import com.oracle.truffle.r.runtime.RError;
+import com.oracle.truffle.r.runtime.RInternalError;
 import com.oracle.truffle.r.runtime.RRuntime;
 import com.oracle.truffle.r.runtime.data.RComplex;
-import com.oracle.truffle.r.runtime.data.RComplexVector;
-import com.oracle.truffle.r.runtime.data.RList;
-import com.oracle.truffle.r.runtime.data.RLogicalVector;
+import com.oracle.truffle.r.runtime.data.RLogical;
 import com.oracle.truffle.r.runtime.data.RNull;
 import com.oracle.truffle.r.runtime.data.RRaw;
-import com.oracle.truffle.r.runtime.data.RRawVector;
-import com.oracle.truffle.r.runtime.data.RStringVector;
-import com.oracle.truffle.r.runtime.data.model.RAbstractDoubleVector;
-import com.oracle.truffle.r.runtime.data.model.RAbstractIntVector;
+import com.oracle.truffle.r.runtime.data.model.RAbstractAtomicVector;
+import com.oracle.truffle.r.runtime.data.model.RAbstractListVector;
 import com.oracle.truffle.r.runtime.data.model.RAbstractVector;
+import com.oracle.truffle.r.runtime.data.nodes.VectorAccess;
+import com.oracle.truffle.r.runtime.data.nodes.VectorAccess.SequentialIterator;
 import com.oracle.truffle.r.runtime.interop.ForeignArray2R;
 import com.oracle.truffle.r.runtime.nodes.RNode;
 import com.oracle.truffle.r.runtime.nodes.RSyntaxNode;
@@ -53,6 +52,8 @@ import com.oracle.truffle.r.runtime.ops.na.NAProfile;
 @ImportStatic(RRuntime.class)
 public abstract class ConvertBooleanNode extends RNode {
 
+    protected static final int ATOMIC_VECTOR_LIMIT = 8;
+
     private final NAProfile naProfile = NAProfile.create();
     private final BranchProfile invalidElementCountBranch = BranchProfile.create();
     @Child private ConvertBooleanNode recursiveConvertBoolean;
@@ -120,10 +121,16 @@ public abstract class ConvertBooleanNode extends RNode {
         return RRuntime.raw2logical(value.getValue());
     }
 
-    private void checkLength(RAbstractVector value) {
-        if (value.getLength() != 1) {
+    @Specialization
+    protected byte doRLogical(RLogical value) {
+        // fast path for very common case, handled also in doAtomicVector
+        return value.getValue();
+    }
+
+    private void checkLength(int length) {
+        if (length != 1) {
             invalidElementCountBranch.enter();
-            if (value.getLength() == 0) {
+            if (length == 0) {
                 throw error(RError.Message.LENGTH_ZERO);
             } else {
                 warning(RError.Message.LENGTH_GT_1);
@@ -131,46 +138,33 @@ public abstract class ConvertBooleanNode extends RNode {
         }
     }
 
-    @Specialization
-    protected byte doIntVector(RAbstractIntVector value) {
-        checkLength(value);
-        return doInt(value.getDataAt(0));
-    }
-
-    @Specialization
-    protected byte doDoubleVector(RAbstractDoubleVector value) {
-        checkLength(value);
-        return doDouble(value.getDataAt(0));
-    }
-
-    @Specialization
-    protected byte doLogicalVector(RLogicalVector value) {
-        checkLength(value);
-        return doLogical(value.getDataAt(0));
-    }
-
-    @Specialization
-    protected byte doComplexVector(RComplexVector value) {
-        checkLength(value);
-        return doComplex(value.getDataAt(0));
-    }
-
-    @Specialization
-    protected byte doStringVector(RStringVector value) {
-        checkLength(value);
-        return doString(value.getDataAt(0));
-    }
-
-    @Specialization
-    protected byte doRawVector(RRawVector value) {
-        checkLength(value);
-        return RRuntime.raw2logical(value.getRawDataAt(0));
+    @Specialization(guards = "access.supports(value)", limit = "ATOMIC_VECTOR_LIMIT")
+    protected byte doVector(RAbstractVector value,
+                    @Cached("value.access()") VectorAccess access) {
+        SequentialIterator it = access.access(value);
+        checkLength(access.getLength(it));
+        access.next(it);
+        switch (access.getType()) {
+            case Integer:
+                return doInt(access.getInt(it));
+            case Double:
+                return doDouble(access.getDouble(it));
+            case Raw:
+                return RRuntime.raw2logical(access.getRaw(it));
+            case Logical:
+                return doLogical(access.getLogical(it));
+            case Character:
+                return doString(access.getString(it));
+            case Complex:
+                return doComplex(access.getComplex(it));
+            default:
+                throw error(RError.Message.ARGUMENT_NOT_INTERPRETABLE_LOGICAL);
+        }
     }
 
-    @Specialization
-    protected byte doRawVector(RList value) {
-        checkLength(value);
-        throw error(RError.Message.ARGUMENT_NOT_INTERPRETABLE_LOGICAL);
+    @Specialization(replaces = "doVector")
+    protected byte doVectorGeneric(RAbstractVector value) {
+        return doVector(value, value.slowPathAccess());
     }
 
     @Specialization(guards = "isForeignObject(obj)")
@@ -192,8 +186,7 @@ public abstract class ConvertBooleanNode extends RNode {
         if (node instanceof ConvertBooleanNode) {
             return (ConvertBooleanNode) node;
         }
-        ConvertBooleanNode result = ConvertBooleanNodeGen.create(node.asRNode());
-        return result;
+        return ConvertBooleanNodeGen.create(node.asRNode());
     }
 
     @Override
diff --git a/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/FastROptions.java b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/FastROptions.java
index 5a9c503079500a97603e9ffdb595104feaa5314e..e4360fc26b053139d0a36d9b630d819376b5d0e1 100644
--- a/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/FastROptions.java
+++ b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/FastROptions.java
@@ -74,6 +74,7 @@ public enum FastROptions {
 
     // Miscellaneous
 
+    IgnoreGraphicsCalls("Silently ignore unimplemented functions from graphics package", false),
     StartupTiming("Records and prints various timestamps during initialization", false);
 
     private final String help;
@@ -92,6 +93,10 @@ public enum FastROptions {
         this.value = defaultValue;
     }
 
+    public boolean isBoolean() {
+        return isBoolean;
+    }
+
     public boolean getBooleanValue() {
         assert isBoolean;
         Object v = value;
diff --git a/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/RLocale.java b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/RLocale.java
index ca3c2f2891a3037cdfdce93a036c7815f916b491..649cb26fc0696879100374bbf4f87c3dafba0364 100644
--- a/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/RLocale.java
+++ b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/RLocale.java
@@ -26,6 +26,9 @@ import java.nio.charset.Charset;
 import java.nio.charset.IllegalCharsetNameException;
 import java.nio.charset.StandardCharsets;
 import java.nio.charset.UnsupportedCharsetException;
+import java.text.Collator;
+import java.text.ParseException;
+import java.text.RuleBasedCollator;
 import java.util.EnumMap;
 import java.util.Locale;
 
@@ -55,6 +58,22 @@ public enum RLocale {
         this.name = "LC_" + name();
     }
 
+    /**
+     * Returns the collator that should be used in order builtin or any place that should sort
+     * elements like order. The {@code Locale} should be retrieved from {@link RContext}.
+     */
+    public static Collator getOrderCollator(Locale locale) {
+        Collator baseCollator = Collator.getInstance(locale);
+        String rules = ((RuleBasedCollator) baseCollator).getRules();
+        Collator collator;
+        try {
+            collator = new RuleBasedCollator(rules.replaceAll("<'\u005f'", "<' '<'\u005f'"));
+        } catch (ParseException e) {
+            throw RInternalError.shouldNotReachHere(e);
+        }
+        return collator;
+    }
+
     public static final class ContextStateImpl implements RContext.ContextState {
         private final EnumMap<RLocale, Locale> locales = new EnumMap<>(RLocale.class);
         private final EnumMap<RLocale, Charset> charsets = new EnumMap<>(RLocale.class);
diff --git a/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/data/RAttributesLayout.java b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/data/RAttributesLayout.java
index ef5fb88f7cb06c6a13dc38ee7dccb3fecb069b6f..6245346502eefc5ea5f4f06ac514c3bfb18b58f1 100644
--- a/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/data/RAttributesLayout.java
+++ b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/data/RAttributesLayout.java
@@ -146,7 +146,21 @@ public final class RAttributesLayout {
     public static DynamicObject copy(DynamicObject attrs) {
         assert isRAttributes(attrs);
 
-        return attrs.copy(attrs.getShape());
+        DynamicObject result = attrs.copy(attrs.getShape());
+        Shape shape = result.getShape();
+        Property prop = shape.getLastProperty();
+        while (prop != null) {
+            Object value = result.get(prop.getKey());
+            if (value instanceof RSharingAttributeStorage) {
+                // There is no simple way to determine the correct reference count here and since
+                // the value will end up in two attributes collections, it will end up being shared
+                // most likely anyway.
+                ((RSharingAttributeStorage) value).makeSharedPermanent();
+            }
+            shape = shape.getParent();
+            prop = shape.getLastProperty();
+        }
+        return result;
     }
 
     @TruffleBoundary
diff --git a/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/data/RPairList.java b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/data/RPairList.java
index 74765b994d27f012599f7653a36f5f8db5e39810..feced1226c62318a28ca3a25b8aea4e7361ba6f7 100644
--- a/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/data/RPairList.java
+++ b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/data/RPairList.java
@@ -31,6 +31,7 @@ import com.oracle.truffle.r.runtime.RInternalError;
 import com.oracle.truffle.r.runtime.RRuntime;
 import com.oracle.truffle.r.runtime.RType;
 import com.oracle.truffle.r.runtime.Utils;
+import com.oracle.truffle.r.runtime.data.RDataFactory.BaseVectorFactory;
 import com.oracle.truffle.r.runtime.data.model.RAbstractContainer;
 import com.oracle.truffle.r.runtime.data.model.RAbstractVector;
 import com.oracle.truffle.r.runtime.data.nodes.FastPathVectorAccess.FastPathFromListAccess;
@@ -270,16 +271,22 @@ public final class RPairList extends RSharingAttributeStorage implements RAbstra
     }
 
     @Override
-    public RSharingAttributeStorage copy() {
-        RPairList result = new RPairList();
+    public RPairList copy() {
+        BaseVectorFactory dataFactory = RDataFactory.getInstance();
+        RPairList curr = dataFactory.createPairList();
+        RPairList result = curr;
         Object original = this;
-        while (!isNull(original)) {
+        while (true) {
             RPairList origList = (RPairList) original;
-            result.car = origList.car;
-            result.tag = origList.tag;
-            result.cdr = new RPairList();
-            result = (RPairList) result.cdr;
+            curr.car = origList.car;
+            curr.tag = origList.tag;
             original = origList.cdr;
+            if (isNull(original)) {
+                curr.cdr = RNull.instance;
+                break;
+            }
+            curr.cdr = dataFactory.createPairList();
+            curr = (RPairList) curr.cdr;
         }
         if (getAttributes() != null) {
             result.initAttributes(RAttributesLayout.copy(getAttributes()));
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 71c091e5f81de87352a639664a550ccea7237616..d1fe132529d3ad8f8f3dc5aa0036a2c8d7fcb8a2 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
@@ -7912,6 +7912,18 @@ name
 #{ as.symbol(as.symbol(123)) }
 `123`
 
+##com.oracle.truffle.r.test.builtins.TestBuiltin_asvector.testAsVector#
+#as.pairlist(as.pairlist(c(1,2,3)))
+[[1]]
+[1] 1
+
+[[2]]
+[1] 2
+
+[[3]]
+[1] 3
+
+
 ##com.oracle.truffle.r.test.builtins.TestBuiltin_asvector.testAsVector#
 #as.vector(NULL, mode='pairlist')
 NULL
@@ -12542,6 +12554,10 @@ NA NA NA NA NA NA NA NA Hey Hey Goodbye
 ##com.oracle.truffle.r.test.builtins.TestBuiltin_cat.testCat#
 #{ cat(sep=" ", "hello") }
 hello
+##com.oracle.truffle.r.test.builtins.TestBuiltin_cat.testCat#Output.IgnoreErrorMessage#
+#{ foo <- function(a,b) cat(a,b); foo(42,); }
+Error in cat(a, b) : argument "b" is missing, with no default
+
 ##com.oracle.truffle.r.test.builtins.TestBuiltin_cat.testCat#
 #{ m <- matrix(as.character(1:6), nrow=2) ; cat(m) }
 1 2 3 4 5 6
@@ -46306,6 +46322,9 @@ $width
 [1] 80
 
 
+##com.oracle.truffle.r.test.builtins.TestBuiltin_options.testOptions#
+#{ options(options(digits = 5)) }
+
 ##com.oracle.truffle.r.test.builtins.TestBuiltin_options.testPrompt#
 #{ options(prompt="abc"); identical(getOption("prompt"), "abc") }
 [1] TRUE
diff --git a/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/builtins/TestBuiltin_asvector.java b/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/builtins/TestBuiltin_asvector.java
index dc1cca11115c51a77cc2705486842ad5efe60d80..67ae5bdcae30836bcd3ca9d60de8b0551b7ad765 100644
--- a/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/builtins/TestBuiltin_asvector.java
+++ b/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/builtins/TestBuiltin_asvector.java
@@ -444,6 +444,7 @@ public class TestBuiltin_asvector extends TestBase {
 
         assertEval("as.vector(NULL, mode='pairlist')");
         assertEval("{ as.vector.cls <- function(x, mode) 42; as.vector(structure(c(1,2), class='cls')); }");
+        assertEval("as.pairlist(as.pairlist(c(1,2,3)))");
     }
 
     @Test
diff --git a/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/builtins/TestBuiltin_cat.java b/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/builtins/TestBuiltin_cat.java
index 9ca7dc6899c8d805079160dfc513149610750423..660ef10f72aa2f2384b33fa6715cbdeb20b35515 100644
--- a/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/builtins/TestBuiltin_cat.java
+++ b/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/builtins/TestBuiltin_cat.java
@@ -78,6 +78,7 @@ public class TestBuiltin_cat extends TestBase {
 
         assertEval("{ cat(c(\"a\", \"b\", \"c\"), \"d\", sep=c(\"-\", \"+\")) }");
         assertEval("{ cat(paste(letters, 100* 1:26), fill = TRUE, labels = paste0(\"{\", 1:10, \"}:\"))}");
+        assertEval(Output.IgnoreErrorMessage, "{ foo <- function(a,b) cat(a,b); foo(42,); }");
     }
 
     @Test
diff --git a/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/builtins/TestBuiltin_options.java b/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/builtins/TestBuiltin_options.java
index 97b6fd5ca14a135fd97d82c11f6cbb9879929d9e..63411ea2a1c1617b0943cf10747ca73e969f2af1 100644
--- a/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/builtins/TestBuiltin_options.java
+++ b/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/builtins/TestBuiltin_options.java
@@ -54,6 +54,7 @@ public class TestBuiltin_options extends TestBase {
         assertEval("{ getOption(NULL) }");
         assertEval("{ getOption(character()) }");
         assertEval("{ options(\"timeout\", \"width\") }");
+        assertEval("{ options(options(digits = 5)) }");
     }
 
     @Test
diff --git a/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/runtime/data/RPairListTests.java b/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/runtime/data/RPairListTests.java
index 04ecbe3bd7112ff3e75835fd90ad3820cbb48a41..0078010f55d99566a4efd72366ecf49df6a8b2bc 100644
--- a/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/runtime/data/RPairListTests.java
+++ b/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/runtime/data/RPairListTests.java
@@ -24,6 +24,7 @@ package com.oracle.truffle.r.test.runtime.data;
 
 import static org.junit.Assert.assertArrayEquals;
 import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertSame;
 
 import java.util.Iterator;
 
@@ -33,6 +34,7 @@ import com.oracle.truffle.r.runtime.data.RDataFactory;
 import com.oracle.truffle.r.runtime.data.RList;
 import com.oracle.truffle.r.runtime.data.RNull;
 import com.oracle.truffle.r.runtime.data.RPairList;
+import com.oracle.truffle.r.runtime.data.RSharingAttributeStorage;
 
 public class RPairListTests {
     @Test
@@ -52,4 +54,16 @@ public class RPairListTests {
         assertArrayEquals(new String[]{"name1", "name2"}, result.getNames().getReadonlyData());
         assertArrayEquals(new Object[]{1, 2}, result.getDataWithoutCopying());
     }
+
+    @Test
+    public void testCopy() {
+        RPairList pairList = RDataFactory.createPairList(1, RDataFactory.createPairList(2, RNull.instance, "name2"), "name1");
+        RPairList copy = pairList.copy();
+        assertEquals(2, copy.getLength());
+        assertEquals("name1", copy.getTag());
+        assertEquals(1, copy.car());
+        assertEquals("name2", ((RPairList) copy.cdr()).getTag());
+        assertEquals(2, ((RPairList) copy.cdr()).car());
+        assertSame(RNull.instance, ((RPairList) copy.cdr()).cdr());
+    }
 }