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 51b362a8ad50a0dcfbbd5611d4c86cebdf494201..8170e1d1b19f680b8335398e890fe242f5ef98cb 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
@@ -574,8 +574,8 @@ public class BasePackage extends RBuiltinPackage {
         add(Tabulate.class, TabulateNodeGen::create);
         add(TempDir.class, TempDirNodeGen::create);
         add(TempFile.class, TempFileNodeGen::create);
-        add(ToLowerOrUpper.ToLower.class, ToLowerOrUpper::createToLower);
-        add(ToLowerOrUpper.ToUpper.class, ToLowerOrUpper::createToUpper);
+        add(ToLowerOrUpper.ToLower.class, ToLowerOrUpperFactory.ToLowerNodeGen::create);
+        add(ToLowerOrUpper.ToUpper.class, ToLowerOrUpperFactory.ToUpperNodeGen::create);
         add(Traceback.class, TracebackNodeGen::create);
         add(TraceFunctions.PrimTrace.class, TraceFunctionsFactory.PrimTraceNodeGen::create);
         add(TraceFunctions.PrimUnTrace.class, TraceFunctionsFactory.PrimUnTraceNodeGen::create);
diff --git a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/Strtrim.java b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/Strtrim.java
index f7fe84aa1e73285af79cd08a77842cf3f4f1eb9d..6124f541a90c1eeefcf644560379ea0a185ed8ba 100644
--- a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/Strtrim.java
+++ b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/Strtrim.java
@@ -15,16 +15,21 @@ package com.oracle.truffle.r.nodes.builtin.base;
 import static com.oracle.truffle.r.runtime.builtins.RBehavior.PURE;
 import static com.oracle.truffle.r.runtime.builtins.RBuiltinKind.INTERNAL;
 
+import java.util.function.BiFunction;
+
+import com.oracle.truffle.api.CompilerDirectives;
 import com.oracle.truffle.api.CompilerDirectives.TruffleBoundary;
-import com.oracle.truffle.api.dsl.Fallback;
+import com.oracle.truffle.api.dsl.Cached;
 import com.oracle.truffle.api.dsl.Specialization;
+import com.oracle.truffle.api.profiles.ConditionProfile;
 import com.oracle.truffle.r.nodes.builtin.CastBuilder;
+import com.oracle.truffle.r.nodes.builtin.CastBuilder.Predef;
 import com.oracle.truffle.r.nodes.builtin.RBuiltinNode;
+import com.oracle.truffle.r.nodes.builtin.base.ToLowerOrUpper.StringMapNode;
 import com.oracle.truffle.r.runtime.RError;
+import com.oracle.truffle.r.runtime.RError.Message;
 import com.oracle.truffle.r.runtime.RRuntime;
 import com.oracle.truffle.r.runtime.builtins.RBuiltin;
-import com.oracle.truffle.r.runtime.data.RAttributeProfiles;
-import com.oracle.truffle.r.runtime.data.RDataFactory;
 import com.oracle.truffle.r.runtime.data.RStringVector;
 import com.oracle.truffle.r.runtime.data.model.RAbstractIntVector;
 import com.oracle.truffle.r.runtime.data.model.RAbstractStringVector;
@@ -32,52 +37,43 @@ import com.oracle.truffle.r.runtime.data.model.RAbstractStringVector;
 @RBuiltin(name = "strtrim", kind = INTERNAL, parameterNames = {"x", "width"}, behavior = PURE)
 public abstract class Strtrim extends RBuiltinNode {
 
-    private RAttributeProfiles attrProfiles = RAttributeProfiles.create();
-
     @Override
     protected void createCasts(CastBuilder casts) {
-        casts.toInteger(1);
+        casts.arg("x").mustBe(Predef.stringValue(), Message.REQUIRES_CHAR_VECTOR, "strtrim()").asStringVector(true, true, true);
+        casts.arg("width").asIntegerVector();
     }
 
     @Specialization
-    protected RStringVector srtrim(RAbstractStringVector x, RAbstractIntVector width) {
+    protected RStringVector srtrim(RAbstractStringVector x, RAbstractIntVector width,
+                    @Cached("create()") StringMapNode mapNode,
+                    @Cached("createBinaryProfile()") ConditionProfile fitsProfile) {
         int len = x.getLength();
         int nw = width.getLength();
         if (nw == 0 || nw < len && (len % nw != 0)) {
+            CompilerDirectives.transferToInterpreter();
             throw RError.error(this, RError.Message.INVALID_ARGUMENT, "width");
         }
         for (int i = 0; i < nw; i++) {
-            int widthi = width.getDataAt(i);
-            if (widthi == RRuntime.INT_NA || widthi < 0) {
+            assert RRuntime.INT_NA < 0; // check for NA folded into < 0
+            if (width.getDataAt(i) < 0) {
+                CompilerDirectives.transferToInterpreter();
                 throw RError.error(this, RError.Message.INVALID_ARGUMENT, "width");
             }
         }
-        String[] data = new String[len];
-        boolean complete = RDataFactory.COMPLETE_VECTOR;
-        for (int i = 0; i < len; i++) {
-            String element = x.getDataAt(i);
-            if (RRuntime.isNA(element)) {
-                data[i] = element;
-                complete = RDataFactory.INCOMPLETE_VECTOR;
-                continue;
-            }
+        BiFunction<String, Integer, String> function = (element, i) -> {
             // TODO multibyte character handling
             int w = width.getDataAt(i % nw);
-            if (w > element.length()) {
-                data[i] = element;
+            if (fitsProfile.profile(w >= element.length())) {
+                return element;
             } else {
-                data[i] = element.substring(0, w);
+                return substring(element, w);
             }
-        }
-        RStringVector result = RDataFactory.createStringVector(data, complete);
-        result.copyAttributesFrom(attrProfiles, x);
-        return result;
+        };
+        return mapNode.apply(x, function);
     }
 
-    @SuppressWarnings("unused")
-    @Fallback
     @TruffleBoundary
-    RStringVector strtrim(Object x, Object width) {
-        throw RError.error(this, RError.Message.REQUIRES_CHAR_VECTOR, "strtrim()");
+    private static String substring(String element, int w) {
+        return element.substring(0, w);
     }
 }
diff --git a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/ToLowerOrUpper.java b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/ToLowerOrUpper.java
index d12bcadb18d22e87bd27a4b3046fe3b117c3aeb4..4010f36ea20ed08601c93d5b0f72456d7b58d100 100644
--- a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/ToLowerOrUpper.java
+++ b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/ToLowerOrUpper.java
@@ -22,73 +22,122 @@
  */
 package com.oracle.truffle.r.nodes.builtin.base;
 
+import static com.oracle.truffle.r.nodes.builtin.CastBuilder.Predef.stringValue;
 import static com.oracle.truffle.r.runtime.builtins.RBehavior.PURE;
 import static com.oracle.truffle.r.runtime.builtins.RBuiltinKind.INTERNAL;
 
+import java.util.function.BiFunction;
+import java.util.function.Function;
+
 import com.oracle.truffle.api.CompilerDirectives.TruffleBoundary;
-import com.oracle.truffle.api.dsl.Cached;
 import com.oracle.truffle.api.dsl.Specialization;
 import com.oracle.truffle.api.profiles.LoopConditionProfile;
 import com.oracle.truffle.r.nodes.attributes.CopyOfRegAttributesNode;
+import com.oracle.truffle.r.nodes.attributes.CopyOfRegAttributesNodeGen;
+import com.oracle.truffle.r.nodes.builtin.CastBuilder;
 import com.oracle.truffle.r.nodes.builtin.RBuiltinNode;
+import com.oracle.truffle.r.nodes.profile.VectorLengthProfile;
 import com.oracle.truffle.r.runtime.RRuntime;
 import com.oracle.truffle.r.runtime.builtins.RBuiltin;
+import com.oracle.truffle.r.runtime.data.RAttributeProfiles;
 import com.oracle.truffle.r.runtime.data.RDataFactory;
 import com.oracle.truffle.r.runtime.data.RStringVector;
 import com.oracle.truffle.r.runtime.data.model.RAbstractStringVector;
-import com.oracle.truffle.r.runtime.nodes.RNode;
+import com.oracle.truffle.r.runtime.nodes.RBaseNode;
 import com.oracle.truffle.r.runtime.ops.na.NACheck;
-import com.oracle.truffle.r.runtime.ops.na.NAProfile;
 
-public abstract class ToLowerOrUpper extends RBuiltinNode {
+public abstract class ToLowerOrUpper {
 
-    @RBuiltin(name = "tolower", kind = INTERNAL, parameterNames = {"x"}, behavior = PURE)
-    public static final class ToLower {
-    }
+    public static final class StringMapNode extends RBaseNode {
 
-    @RBuiltin(name = "toupper", kind = INTERNAL, parameterNames = {"x"}, behavior = PURE)
-    public static final class ToUpper {
-    }
+        private final VectorLengthProfile lengthProfile = VectorLengthProfile.create();
+        private final LoopConditionProfile loopProfile = LoopConditionProfile.createCountingProfile();
+        private final NACheck na = NACheck.create();
+        private final RAttributeProfiles attrProfiles = RAttributeProfiles.create();
 
-    public static ToLowerOrUpper createToLower(RNode[] arguments) {
-        return ToLowerOrUpperNodeGen.create(true, arguments);
-    }
+        @Child private CopyOfRegAttributesNode copyAttributes = CopyOfRegAttributesNodeGen.create();
 
-    public static ToLowerOrUpper createToUpper(RNode[] arguments) {
-        return ToLowerOrUpperNodeGen.create(false, arguments);
-    }
+        private StringMapNode() {
+            // nothing to do
+        }
 
-    private final boolean lower;
+        public static StringMapNode create() {
+            return new StringMapNode();
+        }
 
-    public ToLowerOrUpper(boolean lower) {
-        this.lower = lower;
-    }
+        private String elementFunction(String value, int i, BiFunction<String, Integer, String> function) {
+            return na.check(value) ? RRuntime.STRING_NA : function.apply(value, i);
+        }
+
+        public String apply(String value, BiFunction<String, Integer, String> function) {
+            na.enable(value);
+            return elementFunction(value, 0, function);
+        }
 
-    @TruffleBoundary
-    private String processElement(String value) {
-        return lower ? value.toLowerCase() : value.toUpperCase();
+        public RStringVector apply(RAbstractStringVector vector, BiFunction<String, Integer, String> function) {
+            na.enable(vector);
+            int length = lengthProfile.profile(vector.getLength());
+            String[] stringVector = new String[length];
+            loopProfile.profileCounted(length);
+            for (int i = 0; loopProfile.inject(i < length); i++) {
+                String value = vector.getDataAt(i);
+                stringVector[i] = elementFunction(value, i, function);
+            }
+            RStringVector result = RDataFactory.createStringVector(stringVector, vector.isComplete(), vector.getDimensions(), vector.getNames(attrProfiles));
+            copyAttributes.execute(vector, result);
+            return result;
+        }
     }
 
-    @Specialization
-    protected String toLower(String value, //
-                    @Cached("create()") NAProfile na) {
-        return na.isNA(value) ? RRuntime.STRING_NA : processElement(value);
+    @RBuiltin(name = "tolower", kind = INTERNAL, parameterNames = {"x"}, behavior = PURE)
+    public abstract static class ToLower extends RBuiltinNode {
+
+        @Child private StringMapNode mapNode = StringMapNode.create();
+
+        @Override
+        protected void createCasts(CastBuilder casts) {
+            casts.arg(0, "x").mustBe(stringValue()).asStringVector(true, true, true);
+        }
+
+        @TruffleBoundary
+        private static String processElement(String value, int i) {
+            return value.toLowerCase();
+        }
+
+        @Specialization
+        protected String toLower(String value) {
+            return mapNode.apply(value, ToLower::processElement);
+        }
+
+        @Specialization
+        protected RStringVector toLower(RAbstractStringVector vector) {
+            return mapNode.apply(vector, ToLower::processElement);
+        }
     }
 
-    @Specialization
-    protected RStringVector toLower(RAbstractStringVector vector, //
-                    @Cached("createCountingProfile()") LoopConditionProfile loopProfile, //
-                    @Cached("create()") NACheck na, //
-                    @Cached("create()") CopyOfRegAttributesNode copyAttributes) {
-        na.enable(vector);
-        String[] stringVector = new String[vector.getLength()];
-        loopProfile.profileCounted(vector.getLength());
-        for (int i = 0; loopProfile.inject(i < vector.getLength()); i++) {
-            String value = vector.getDataAt(i);
-            stringVector[i] = na.check(value) ? RRuntime.STRING_NA : processElement(value);
+    @RBuiltin(name = "toupper", kind = INTERNAL, parameterNames = {"x"}, behavior = PURE)
+    public abstract static class ToUpper extends RBuiltinNode {
+
+        @Child private StringMapNode mapNode = StringMapNode.create();
+
+        @Override
+        protected void createCasts(CastBuilder casts) {
+            casts.arg(0, "x").mustBe(stringValue()).asStringVector(true, true, true);
+        }
+
+        @TruffleBoundary
+        private static String processElement(String value, int i) {
+            return value.toUpperCase();
+        }
+
+        @Specialization
+        protected String toLower(String value) {
+            return mapNode.apply(value, ToUpper::processElement);
+        }
+
+        @Specialization
+        protected RStringVector toLower(RAbstractStringVector vector) {
+            return mapNode.apply(vector, ToUpper::processElement);
         }
-        RStringVector result = RDataFactory.createStringVector(stringVector, vector.isComplete(), vector.getDimensions());
-        copyAttributes.execute(vector, result);
-        return result;
     }
 }
diff --git a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/access/ReadVariadicComponentNode.java b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/access/ReadVariadicComponentNode.java
index 46ab6dc79f9f12af5c770c05d4dd1f2f2a07cfe9..1441a1741586f7b8c1495521281adfb2dabccba5 100644
--- a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/access/ReadVariadicComponentNode.java
+++ b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/access/ReadVariadicComponentNode.java
@@ -102,7 +102,7 @@ public class ReadVariadicComponentNode extends RSourceSectionNode implements RSy
 
     @Override
     public String getIdentifier() {
-        return getPrintForm();
+        return getPrintForm().intern();
     }
 
     @Override
diff --git a/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/nodes/RSyntaxLookup.java b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/nodes/RSyntaxLookup.java
index 705968c91b77d672bdbac6ee8212c7130ac7a259..ac2cfe029130c6db14079f91223bc1a623d59354 100644
--- a/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/nodes/RSyntaxLookup.java
+++ b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/nodes/RSyntaxLookup.java
@@ -29,6 +29,9 @@ import com.oracle.truffle.api.source.SourceSection;
  */
 public interface RSyntaxLookup extends RSyntaxElement {
 
+    /**
+     * @return The identifier that this lookup represents - this needs to be an interned string.
+     */
     String getIdentifier();
 
     boolean isFunctionLookup();
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 a24724055e6f850aedb069f9e7dbabecde41a50f..ea9e318c809ae60051f718f3956f08ed1b815ae1 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
@@ -45982,6 +45982,16 @@ character(0)
 #argv <- list(character(0), 8L); .Internal(strtoi(argv[[1]], argv[[2]]))
 integer(0)
 
+##com.oracle.truffle.r.test.builtins.TestBuiltin_strtrim.teststrtrim
+#v <- c('a', 'fooooo', 'bbbbbb', 'cccccccccc', 'dd', NA); names(v) <- as.character(1:6); strtrim(v, c(2, 5))
+      1       2       3       4       5       6
+    "a" "foooo"    "bb" "ccccc"    "dd"      NA
+
+##com.oracle.truffle.r.test.builtins.TestBuiltin_strtrim.teststrtrim
+#v <- c('a', 'fooooo', 'bbbbbb', 'cccccccccc', 'dd', NA); names(v) <- as.character(1:6); strtrim(v, c(2L, 5L))
+      1       2       3       4       5       6
+    "a" "foooo"    "bb" "ccccc"    "dd"      NA
+
 ##com.oracle.truffle.r.test.builtins.TestBuiltin_strtrim.teststrtrim1
 #argv <- list(c('\'time\'', '\'status\''), 128); .Internal(strtrim(argv[[1]], argv[[2]]))
 [1] "'time'"   "'status'"
diff --git a/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/builtins/TestBuiltin_strtrim.java b/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/builtins/TestBuiltin_strtrim.java
index 6c566f53a4cd418c70b1f9cf22aeb9019ebc992c..00fc2dc52149e953dff0057469a515912a4decb2 100644
--- a/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/builtins/TestBuiltin_strtrim.java
+++ b/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/builtins/TestBuiltin_strtrim.java
@@ -51,4 +51,10 @@ public class TestBuiltin_strtrim extends TestBase {
     public void teststrtrim8() {
         assertEval("argv <- list(character(0), 40L); .Internal(strtrim(argv[[1]], argv[[2]]))");
     }
+
+    @Test
+    public void teststrtrim() {
+        assertEval("v <- c('a', 'fooooo', 'bbbbbb', 'cccccccccc', 'dd', NA); names(v) <- as.character(1:6); strtrim(v, c(2L, 5L))");
+        assertEval("v <- c('a', 'fooooo', 'bbbbbb', 'cccccccccc', 'dd', NA); names(v) <- as.character(1:6); strtrim(v, c(2, 5))");
+    }
 }
diff --git a/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/builtins/TestBuiltin_tolower.java b/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/builtins/TestBuiltin_tolower.java
index 8b0588b2bdd7b3dbe88f9dcc5db85d1dbc65c20f..f216fb17383d13f45e41e65f7a756002c2cc96a6 100644
--- a/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/builtins/TestBuiltin_tolower.java
+++ b/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/builtins/TestBuiltin_tolower.java
@@ -39,7 +39,7 @@ public class TestBuiltin_tolower extends TestBase {
 
     @Test
     public void testtolower5() {
-        assertEval(Ignored.Unimplemented, "argv <- list(structure('base', .Names = 'Priority')); .Internal(tolower(argv[[1]]))");
+        assertEval("argv <- list(structure('base', .Names = 'Priority')); .Internal(tolower(argv[[1]]))");
     }
 
     @Test
@@ -57,8 +57,9 @@ public class TestBuiltin_tolower extends TestBase {
         assertEval("{ tolower(c(\"Hello\",\"ByE\")) }");
         assertEval("{ tolower(c()) }");
 
+        // double-to-string conversion problem
         assertEval(Ignored.OutputFormatting, "{ tolower(1E100) }");
-        assertEval(Ignored.Unimplemented, "{ tolower(c(a=\"HI\", \"HELlo\")) }");
+        assertEval("{ tolower(c(a=\"HI\", \"HELlo\")) }");
         assertEval("{ tolower(NA) }");
 
         assertEval("tolower(c('NA', 'na'))");
diff --git a/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/builtins/TestBuiltin_toupper.java b/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/builtins/TestBuiltin_toupper.java
index d00b82523eba4d16051e8f3682407f4e391229be..a6a2008deac27591833cea3559e7b408bbcffd1f 100644
--- a/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/builtins/TestBuiltin_toupper.java
+++ b/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/builtins/TestBuiltin_toupper.java
@@ -34,8 +34,7 @@ public class TestBuiltin_toupper extends TestBase {
 
     @Test
     public void testtoupper4() {
-        assertEval(Ignored.Unimplemented,
-                        "argv <- list(structure(c('BasicClasses', 'Classes', 'Documentation', 'environment-class', 'GenericFunctions', 'language-class', 'LinearMethodsList-class', 'MethodDefinition-class', 'MethodWithNext-class', 'Methods', 'MethodsList-class', 'callNextMethod', 'ObjectsWithPackage-class', 'S3Part', 'S4groupGeneric', 'SClassExtension-class', 'StructureClasses', 'TraceClasses', 'as', 'callGeneric', 'canCoerce', 'cbind2', 'className', 'classRepresentation-class', 'classesToAM', 'dotsMethods', 'evalSource', 'findClass', 'findMethods', 'fixPre1.8', 'genericFunction-class', 'getClass', 'getMethod', 'getPackageName', 'hasArg', 'implicitGeneric', 'inheritedSlotNames', 'initialize-methods', 'is', 'isSealedMethod', 'LocalReferenceClasses', 'method.skeleton', 'new', 'nonStructure-class', 'promptClass', 'promptMethods', 'ReferenceClasses', 'representation', 'selectSuperClasses', 'setClass', 'setClassUnion', 'setGeneric', 'setLoadActions', 'setMethod', 'setOldClass', 'makeClassRepresentation', 'show', 'showMethods', 'signature-class', 'slot', 'envRefClass-class', 'testInheritedMethods', 'validObject', '.BasicFunsList'), .Names = c('/home/lzhao/tmp/RtmpZy1R7l/ltx5573594f0cc9/BasicClasses.tex', '/home/lzhao/tmp/RtmpZy1R7l/ltx5573594f0cc9/Classes.tex', '/home/lzhao/tmp/RtmpZy1R7l/ltx5573594f0cc9/Documentation.tex', '/home/lzhao/tmp/RtmpZy1R7l/ltx5573594f0cc9/EnvironmentClass.tex', '/home/lzhao/tmp/RtmpZy1R7l/ltx5573594f0cc9/GenericFunctions.tex', '/home/lzhao/tmp/RtmpZy1R7l/ltx5573594f0cc9/LanguageClasses.tex', '/home/lzhao/tmp/RtmpZy1R7l/ltx5573594f0cc9/LinearMethodsList-class.tex', '/home/lzhao/tmp/RtmpZy1R7l/ltx5573594f0cc9/MethodDefinition-class.tex', '/home/lzhao/tmp/RtmpZy1R7l/ltx5573594f0cc9/MethodWithNext-class.tex', '/home/lzhao/tmp/RtmpZy1R7l/ltx5573594f0cc9/Methods.tex', '/home/lzhao/tmp/RtmpZy1R7l/ltx5573594f0cc9/MethodsList-class.tex', '/home/lzhao/tmp/RtmpZy1R7l/ltx5573594f0cc9/NextMethod.tex', '/home/lzhao/tmp/RtmpZy1R7l/ltx5573594f0cc9/ObjectsWithPackage-class.tex', '/home/lzhao/tmp/RtmpZy1R7l/ltx5573594f0cc9/S3Part.tex', '/home/lzhao/tmp/RtmpZy1R7l/ltx5573594f0cc9/S4groupGeneric.tex', '/home/lzhao/tmp/RtmpZy1R7l/ltx5573594f0cc9/SClassExtension-class.tex', '/home/lzhao/tmp/RtmpZy1R7l/ltx5573594f0cc9/StructureClasses.tex', '/home/lzhao/tmp/RtmpZy1R7l/ltx5573594f0cc9/TraceClasses.tex', '/home/lzhao/tmp/RtmpZy1R7l/ltx5573594f0cc9/as.tex', '/home/lzhao/tmp/RtmpZy1R7l/ltx5573594f0cc9/callGeneric.tex', '/home/lzhao/tmp/RtmpZy1R7l/ltx5573594f0cc9/canCoerce.tex', '/home/lzhao/tmp/RtmpZy1R7l/ltx5573594f0cc9/cbind2.tex', '/home/lzhao/tmp/RtmpZy1R7l/ltx5573594f0cc9/className.tex', '/home/lzhao/tmp/RtmpZy1R7l/ltx5573594f0cc9/classRepresentation-class.tex', '/home/lzhao/tmp/RtmpZy1R7l/ltx5573594f0cc9/classesToAM.tex', '/home/lzhao/tmp/RtmpZy1R7l/ltx5573594f0cc9/dotsMethods.tex', '/home/lzhao/tmp/RtmpZy1R7l/ltx5573594f0cc9/evalSource.tex', '/home/lzhao/tmp/RtmpZy1R7l/ltx5573594f0cc9/findClass.tex', '/home/lzhao/tmp/RtmpZy1R7l/ltx5573594f0cc9/findMethods.tex', '/home/lzhao/tmp/RtmpZy1R7l/ltx5573594f0cc9/fixPrevious.tex', '/home/lzhao/tmp/RtmpZy1R7l/ltx5573594f0cc9/genericFunction-class.tex', '/home/lzhao/tmp/RtmpZy1R7l/ltx5573594f0cc9/getClass.tex', '/home/lzhao/tmp/RtmpZy1R7l/ltx5573594f0cc9/getMethod.tex', '/home/lzhao/tmp/RtmpZy1R7l/ltx5573594f0cc9/getPackageName.tex', '/home/lzhao/tmp/RtmpZy1R7l/ltx5573594f0cc9/hasArg.tex', '/home/lzhao/tmp/RtmpZy1R7l/ltx5573594f0cc9/implicitGeneric.tex', '/home/lzhao/tmp/RtmpZy1R7l/ltx5573594f0cc9/inheritedSlotNames.tex', '/home/lzhao/tmp/RtmpZy1R7l/ltx5573594f0cc9/initialize-methods.tex', '/home/lzhao/tmp/RtmpZy1R7l/ltx5573594f0cc9/is.tex', '/home/lzhao/tmp/RtmpZy1R7l/ltx5573594f0cc9/isSealedMethod.tex', '/home/lzhao/tmp/RtmpZy1R7l/ltx5573594f0cc9/localRefClass.tex', '/home/lzhao/tmp/RtmpZy1R7l/ltx5573594f0cc9/method.skeleton.tex', '/home/lzhao/tmp/RtmpZy1R7l/ltx5573594f0cc9/new.tex', '/home/lzhao/tmp/RtmpZy1R7l/ltx5573594f0cc9/nonStructure-class.tex', '/home/lzhao/tmp/RtmpZy1R7l/ltx5573594f0cc9/promptClass.tex', '/home/lzhao/tmp/RtmpZy1R7l/ltx5573594f0cc9/promptMethods.tex', '/home/lzhao/tmp/RtmpZy1R7l/ltx5573594f0cc9/refClass.tex', '/home/lzhao/tmp/RtmpZy1R7l/ltx5573594f0cc9/representation.tex', '/home/lzhao/tmp/RtmpZy1R7l/ltx5573594f0cc9/selectSuperClasses.tex', '/home/lzhao/tmp/RtmpZy1R7l/ltx5573594f0cc9/setClass.tex', '/home/lzhao/tmp/RtmpZy1R7l/ltx5573594f0cc9/setClassUnion.tex', '/home/lzhao/tmp/RtmpZy1R7l/ltx5573594f0cc9/setGeneric.tex', '/home/lzhao/tmp/RtmpZy1R7l/ltx5573594f0cc9/setLoadActions.tex', '/home/lzhao/tmp/RtmpZy1R7l/ltx5573594f0cc9/setMethod.tex', '/home/lzhao/tmp/RtmpZy1R7l/ltx5573594f0cc9/setOldClass.tex', '/home/lzhao/tmp/RtmpZy1R7l/ltx5573594f0cc9/setSClass.tex', '/home/lzhao/tmp/RtmpZy1R7l/ltx5573594f0cc9/show.tex', '/home/lzhao/tmp/RtmpZy1R7l/ltx5573594f0cc9/showMethods.tex', '/home/lzhao/tmp/RtmpZy1R7l/ltx5573594f0cc9/signature-class.tex', '/home/lzhao/tmp/RtmpZy1R7l/ltx5573594f0cc9/slot.tex', '/home/lzhao/tmp/RtmpZy1R7l/ltx5573594f0cc9/stdRefClass.tex', '/home/lzhao/tmp/RtmpZy1R7l/ltx5573594f0cc9/testInheritedMethods.tex', '/home/lzhao/tmp/RtmpZy1R7l/ltx5573594f0cc9/validObject.tex', '/home/lzhao/tmp/RtmpZy1R7l/ltx5573594f0cc9/zBasicFunsList.tex'))); .Internal(toupper(argv[[1]]))");
+        assertEval("argv <- list(structure(c('BasicClasses', 'Classes', 'Documentation', 'environment-class', 'GenericFunctions', 'language-class', 'LinearMethodsList-class', 'MethodDefinition-class', 'MethodWithNext-class', 'Methods', 'MethodsList-class', 'callNextMethod', 'ObjectsWithPackage-class', 'S3Part', 'S4groupGeneric', 'SClassExtension-class', 'StructureClasses', 'TraceClasses', 'as', 'callGeneric', 'canCoerce', 'cbind2', 'className', 'classRepresentation-class', 'classesToAM', 'dotsMethods', 'evalSource', 'findClass', 'findMethods', 'fixPre1.8', 'genericFunction-class', 'getClass', 'getMethod', 'getPackageName', 'hasArg', 'implicitGeneric', 'inheritedSlotNames', 'initialize-methods', 'is', 'isSealedMethod', 'LocalReferenceClasses', 'method.skeleton', 'new', 'nonStructure-class', 'promptClass', 'promptMethods', 'ReferenceClasses', 'representation', 'selectSuperClasses', 'setClass', 'setClassUnion', 'setGeneric', 'setLoadActions', 'setMethod', 'setOldClass', 'makeClassRepresentation', 'show', 'showMethods', 'signature-class', 'slot', 'envRefClass-class', 'testInheritedMethods', 'validObject', '.BasicFunsList'), .Names = c('/home/lzhao/tmp/RtmpZy1R7l/ltx5573594f0cc9/BasicClasses.tex', '/home/lzhao/tmp/RtmpZy1R7l/ltx5573594f0cc9/Classes.tex', '/home/lzhao/tmp/RtmpZy1R7l/ltx5573594f0cc9/Documentation.tex', '/home/lzhao/tmp/RtmpZy1R7l/ltx5573594f0cc9/EnvironmentClass.tex', '/home/lzhao/tmp/RtmpZy1R7l/ltx5573594f0cc9/GenericFunctions.tex', '/home/lzhao/tmp/RtmpZy1R7l/ltx5573594f0cc9/LanguageClasses.tex', '/home/lzhao/tmp/RtmpZy1R7l/ltx5573594f0cc9/LinearMethodsList-class.tex', '/home/lzhao/tmp/RtmpZy1R7l/ltx5573594f0cc9/MethodDefinition-class.tex', '/home/lzhao/tmp/RtmpZy1R7l/ltx5573594f0cc9/MethodWithNext-class.tex', '/home/lzhao/tmp/RtmpZy1R7l/ltx5573594f0cc9/Methods.tex', '/home/lzhao/tmp/RtmpZy1R7l/ltx5573594f0cc9/MethodsList-class.tex', '/home/lzhao/tmp/RtmpZy1R7l/ltx5573594f0cc9/NextMethod.tex', '/home/lzhao/tmp/RtmpZy1R7l/ltx5573594f0cc9/ObjectsWithPackage-class.tex', '/home/lzhao/tmp/RtmpZy1R7l/ltx5573594f0cc9/S3Part.tex', '/home/lzhao/tmp/RtmpZy1R7l/ltx5573594f0cc9/S4groupGeneric.tex', '/home/lzhao/tmp/RtmpZy1R7l/ltx5573594f0cc9/SClassExtension-class.tex', '/home/lzhao/tmp/RtmpZy1R7l/ltx5573594f0cc9/StructureClasses.tex', '/home/lzhao/tmp/RtmpZy1R7l/ltx5573594f0cc9/TraceClasses.tex', '/home/lzhao/tmp/RtmpZy1R7l/ltx5573594f0cc9/as.tex', '/home/lzhao/tmp/RtmpZy1R7l/ltx5573594f0cc9/callGeneric.tex', '/home/lzhao/tmp/RtmpZy1R7l/ltx5573594f0cc9/canCoerce.tex', '/home/lzhao/tmp/RtmpZy1R7l/ltx5573594f0cc9/cbind2.tex', '/home/lzhao/tmp/RtmpZy1R7l/ltx5573594f0cc9/className.tex', '/home/lzhao/tmp/RtmpZy1R7l/ltx5573594f0cc9/classRepresentation-class.tex', '/home/lzhao/tmp/RtmpZy1R7l/ltx5573594f0cc9/classesToAM.tex', '/home/lzhao/tmp/RtmpZy1R7l/ltx5573594f0cc9/dotsMethods.tex', '/home/lzhao/tmp/RtmpZy1R7l/ltx5573594f0cc9/evalSource.tex', '/home/lzhao/tmp/RtmpZy1R7l/ltx5573594f0cc9/findClass.tex', '/home/lzhao/tmp/RtmpZy1R7l/ltx5573594f0cc9/findMethods.tex', '/home/lzhao/tmp/RtmpZy1R7l/ltx5573594f0cc9/fixPrevious.tex', '/home/lzhao/tmp/RtmpZy1R7l/ltx5573594f0cc9/genericFunction-class.tex', '/home/lzhao/tmp/RtmpZy1R7l/ltx5573594f0cc9/getClass.tex', '/home/lzhao/tmp/RtmpZy1R7l/ltx5573594f0cc9/getMethod.tex', '/home/lzhao/tmp/RtmpZy1R7l/ltx5573594f0cc9/getPackageName.tex', '/home/lzhao/tmp/RtmpZy1R7l/ltx5573594f0cc9/hasArg.tex', '/home/lzhao/tmp/RtmpZy1R7l/ltx5573594f0cc9/implicitGeneric.tex', '/home/lzhao/tmp/RtmpZy1R7l/ltx5573594f0cc9/inheritedSlotNames.tex', '/home/lzhao/tmp/RtmpZy1R7l/ltx5573594f0cc9/initialize-methods.tex', '/home/lzhao/tmp/RtmpZy1R7l/ltx5573594f0cc9/is.tex', '/home/lzhao/tmp/RtmpZy1R7l/ltx5573594f0cc9/isSealedMethod.tex', '/home/lzhao/tmp/RtmpZy1R7l/ltx5573594f0cc9/localRefClass.tex', '/home/lzhao/tmp/RtmpZy1R7l/ltx5573594f0cc9/method.skeleton.tex', '/home/lzhao/tmp/RtmpZy1R7l/ltx5573594f0cc9/new.tex', '/home/lzhao/tmp/RtmpZy1R7l/ltx5573594f0cc9/nonStructure-class.tex', '/home/lzhao/tmp/RtmpZy1R7l/ltx5573594f0cc9/promptClass.tex', '/home/lzhao/tmp/RtmpZy1R7l/ltx5573594f0cc9/promptMethods.tex', '/home/lzhao/tmp/RtmpZy1R7l/ltx5573594f0cc9/refClass.tex', '/home/lzhao/tmp/RtmpZy1R7l/ltx5573594f0cc9/representation.tex', '/home/lzhao/tmp/RtmpZy1R7l/ltx5573594f0cc9/selectSuperClasses.tex', '/home/lzhao/tmp/RtmpZy1R7l/ltx5573594f0cc9/setClass.tex', '/home/lzhao/tmp/RtmpZy1R7l/ltx5573594f0cc9/setClassUnion.tex', '/home/lzhao/tmp/RtmpZy1R7l/ltx5573594f0cc9/setGeneric.tex', '/home/lzhao/tmp/RtmpZy1R7l/ltx5573594f0cc9/setLoadActions.tex', '/home/lzhao/tmp/RtmpZy1R7l/ltx5573594f0cc9/setMethod.tex', '/home/lzhao/tmp/RtmpZy1R7l/ltx5573594f0cc9/setOldClass.tex', '/home/lzhao/tmp/RtmpZy1R7l/ltx5573594f0cc9/setSClass.tex', '/home/lzhao/tmp/RtmpZy1R7l/ltx5573594f0cc9/show.tex', '/home/lzhao/tmp/RtmpZy1R7l/ltx5573594f0cc9/showMethods.tex', '/home/lzhao/tmp/RtmpZy1R7l/ltx5573594f0cc9/signature-class.tex', '/home/lzhao/tmp/RtmpZy1R7l/ltx5573594f0cc9/slot.tex', '/home/lzhao/tmp/RtmpZy1R7l/ltx5573594f0cc9/stdRefClass.tex', '/home/lzhao/tmp/RtmpZy1R7l/ltx5573594f0cc9/testInheritedMethods.tex', '/home/lzhao/tmp/RtmpZy1R7l/ltx5573594f0cc9/validObject.tex', '/home/lzhao/tmp/RtmpZy1R7l/ltx5573594f0cc9/zBasicFunsList.tex'))); .Internal(toupper(argv[[1]]))");
     }
 
     @Test
@@ -51,6 +50,6 @@ public class TestBuiltin_toupper extends TestBase {
 
         assertEval(Ignored.OutputFormatting, "{ toupper(1E100) }");
         assertEval("{ m <- matrix(\"hi\") ; toupper(m) }");
-        assertEval(Ignored.Unimplemented, "{ toupper(c(a=\"hi\", \"hello\")) }");
+        assertEval("{ toupper(c(a=\"hi\", \"hello\")) }");
     }
 }