diff --git a/com.oracle.truffle.r.nodes.test/src/com/oracle/truffle/r/nodes/builtin/CastBuilderTest.java b/com.oracle.truffle.r.nodes.test/src/com/oracle/truffle/r/nodes/builtin/CastBuilderTest.java
index 14bd470438b73db082a96dee6f152da748ca227b..24e9d47732f8070bc3d3abaaa840a2faead9264a 100644
--- a/com.oracle.truffle.r.nodes.test/src/com/oracle/truffle/r/nodes/builtin/CastBuilderTest.java
+++ b/com.oracle.truffle.r.nodes.test/src/com/oracle/truffle/r/nodes/builtin/CastBuilderTest.java
@@ -22,6 +22,7 @@
  */
 package com.oracle.truffle.r.nodes.builtin;
 
+import static com.oracle.truffle.r.nodes.builtin.CastBuilder.Predef.anyValue;
 import static com.oracle.truffle.r.nodes.builtin.CastBuilder.Predef.abstractVectorValue;
 import static com.oracle.truffle.r.nodes.builtin.CastBuilder.Predef.asBoolean;
 import static com.oracle.truffle.r.nodes.builtin.CastBuilder.Predef.asInteger;
@@ -861,6 +862,26 @@ public class CastBuilderTest {
         Assert.assertEquals("abc", cast("abc"));
     }
 
+    @Test
+    public void testWarningInElseBranchOfMapIf() {
+        arg.mapIf(numericValue(),
+                        chain(asIntegerVector()).with(findFirst().integerElement()).end(),
+                        chain(asIntegerVector()).with(Predef.shouldBe(anyValue().not(), RError.NO_CALLER, RError.Message.NA_INTRODUCED_COERCION)).end());
+
+        Assert.assertEquals(1, cast(1));
+        Assert.assertEquals(1, cast("1"));
+        Assert.assertEquals(RError.Message.NA_INTRODUCED_COERCION.message, CastNode.getLastWarning());
+    }
+
+    @Test
+    public void testWarningInTrueBranchOfMapIf() {
+        arg.allowNull().mapIf(stringValue(), chain(asStringVector()).with(shouldBe(anyValue().not(),
+                        RError.SHOW_CALLER, RError.Message.NA_INTRODUCED_COERCION)).end(),
+                        asIntegerVector());
+        Assert.assertEquals("1", cast("1"));
+        Assert.assertEquals(RError.Message.NA_INTRODUCED_COERCION.message, CastNode.getLastWarning());
+    }
+
     /**
      * Casts given object using the configured pipeline in {@link #arg}.
      */
diff --git a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/builtin/CastBuilder.java b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/builtin/CastBuilder.java
index 4d4279b45d537e5e58ad13fd35aec0d17e0b1266..98aedf151d9e5d4d1441b6b3313700816ca26755 100644
--- a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/builtin/CastBuilder.java
+++ b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/builtin/CastBuilder.java
@@ -321,26 +321,50 @@ public final class CastBuilder {
             return new CoercionStep<>(RType.Integer, false);
         }
 
+        public static <T> PipelineStep<T, Integer> asInteger(RBaseNode messageCallerObj) {
+            return new CoercionStep<>(RType.Integer, false, false, false, false, true, messageCallerObj);
+        }
+
         public static <T> PipelineStep<T, RAbstractIntVector> asIntegerVector() {
             return new CoercionStep<>(RType.Integer, true);
         }
 
+        public static <T> PipelineStep<T, RAbstractIntVector> asIntegerVector(RBaseNode messageCallerObj) {
+            return new CoercionStep<>(RType.Integer, true, false, false, false, true, messageCallerObj);
+        }
+
         public static <T> PipelineStep<T, RAbstractIntVector> asIntegerVector(boolean preserveNames, boolean preserveDimensions, boolean preserveAttributes) {
-            return new CoercionStep<>(RType.Integer, true, preserveNames, preserveDimensions, preserveAttributes);
+            return new CoercionStep<>(RType.Integer, true, preserveNames, preserveDimensions, preserveAttributes, true, null);
+        }
+
+        public static <T> PipelineStep<T, RAbstractIntVector> asIntegerVector(boolean preserveNames, boolean preserveDimensions, boolean preserveAttributes, RBaseNode messageCallerObj) {
+            return new CoercionStep<>(RType.Integer, true, preserveNames, preserveDimensions, preserveAttributes, true, messageCallerObj);
         }
 
         public static <T> PipelineStep<T, Double> asDouble() {
             return new CoercionStep<>(RType.Double, false);
         }
 
+        public static <T> PipelineStep<T, Double> asDouble(RBaseNode messageCallerObj) {
+            return new CoercionStep<>(RType.Double, false, false, false, false, true, messageCallerObj);
+        }
+
         public static <T> PipelineStep<T, RAbstractDoubleVector> asDoubleVector() {
             return new CoercionStep<>(RType.Double, true);
         }
 
+        public static <T> PipelineStep<T, RAbstractDoubleVector> asDoubleVector(RBaseNode messageCallerObj) {
+            return new CoercionStep<>(RType.Double, true, false, false, false, true, messageCallerObj);
+        }
+
         public static <T> PipelineStep<T, RAbstractDoubleVector> asDoubleVector(boolean preserveNames, boolean preserveDimensions, boolean preserveAttributes) {
             return new CoercionStep<>(RType.Double, true, preserveNames, preserveDimensions, preserveAttributes);
         }
 
+        public static <T> PipelineStep<T, RAbstractDoubleVector> asDoubleVector(boolean preserveNames, boolean preserveDimensions, boolean preserveAttributes, RBaseNode messageCallerObj) {
+            return new CoercionStep<>(RType.Double, true, preserveNames, preserveDimensions, preserveAttributes, true, messageCallerObj);
+        }
+
         public static <T> PipelineStep<T, String> asString() {
             return new CoercionStep<>(RType.Character, false);
         }
@@ -357,6 +381,10 @@ public final class CastBuilder {
             return new CoercionStep<>(RType.Complex, true);
         }
 
+        public static <T> PipelineStep<T, RAbstractComplexVector> asComplex(RBaseNode messageCallerObj) {
+            return new CoercionStep<>(RType.Complex, false, false, false, false, true, messageCallerObj);
+        }
+
         public static <T> PipelineStep<T, RAbstractRawVector> asRawVector() {
             return new CoercionStep<>(RType.Raw, true);
         }
@@ -365,12 +393,24 @@ public final class CastBuilder {
             return new CoercionStep<>(RType.Logical, false);
         }
 
+        public static <T> PipelineStep<T, Byte> asLogical(RBaseNode messageCallerObj) {
+            return new CoercionStep<>(RType.Logical, false, false, false, false, true, messageCallerObj);
+        }
+
         public static <T> PipelineStep<T, RAbstractLogicalVector> asLogicalVector() {
             return new CoercionStep<>(RType.Logical, true);
         }
 
+        public static <T> PipelineStep<T, RAbstractLogicalVector> asLogicalVector(RBaseNode messageCallerObj) {
+            return new CoercionStep<>(RType.Logical, true, false, false, false, true, messageCallerObj);
+        }
+
         public static <T> PipelineStep<T, RAbstractLogicalVector> asLogicalVector(boolean preserveNames, boolean preserveDimensions, boolean preserveAttributes) {
-            return new CoercionStep<>(RType.Logical, true, preserveNames, preserveDimensions, preserveAttributes, false);
+            return new CoercionStep<>(RType.Logical, true, preserveNames, preserveDimensions, preserveAttributes, false, null);
+        }
+
+        public static <T> PipelineStep<T, RAbstractLogicalVector> asLogicalVector(boolean preserveNames, boolean preserveDimensions, boolean preserveAttributes, RBaseNode messageCallerObj) {
+            return new CoercionStep<>(RType.Logical, true, preserveNames, preserveDimensions, preserveAttributes, true, messageCallerObj);
         }
 
         public static PipelineStep<Byte, Boolean> asBoolean() {
@@ -382,7 +422,7 @@ public final class CastBuilder {
         }
 
         public static <T> PipelineStep<T, RAbstractVector> asVector(boolean preserveNonVector) {
-            return new CoercionStep<>(RType.Any, true, false, false, false, preserveNonVector);
+            return new CoercionStep<>(RType.Any, true, false, false, false, preserveNonVector, null);
         }
 
         /**
diff --git a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/builtin/casts/PipelineStep.java b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/builtin/casts/PipelineStep.java
index b4285ff050a05ff5033a7f4217bf2d278654a65d..e6bbe5e5a4dd973d1f44c9005321aa054bad2640 100644
--- a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/builtin/casts/PipelineStep.java
+++ b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/builtin/casts/PipelineStep.java
@@ -25,6 +25,7 @@ package com.oracle.truffle.r.nodes.builtin.casts;
 import com.oracle.truffle.r.runtime.RType;
 import com.oracle.truffle.r.runtime.data.RAttributable;
 import com.oracle.truffle.r.runtime.data.model.RAbstractVector;
+import com.oracle.truffle.r.runtime.nodes.RBaseNode;
 
 /**
  * Represents a single step in the cast pipeline. {@code PipelineStep}, {@code Mapper} and
@@ -206,6 +207,7 @@ public abstract class PipelineStep<T, R> {
         public final boolean preserveNames;
         public final boolean preserveDimensions;
         public final boolean preserveAttributes;
+        public final RBaseNode messageCallObj;
 
         /**
          * Whether RNull/RMissing should be preserved, or converted to an empty list.
@@ -218,26 +220,31 @@ public abstract class PipelineStep<T, R> {
         public final boolean vectorCoercion;
 
         public CoercionStep(RType type, boolean vectorCoercion) {
-            this(type, vectorCoercion, false, false, false, true);
+            this(type, vectorCoercion, false, false, false, true, null);
         }
 
         public CoercionStep(RType type, boolean vectorCoercion, boolean preserveNames, boolean preserveDimensions, boolean preserveAttributes) {
-            this(type, vectorCoercion, preserveNames, preserveDimensions, preserveAttributes, true);
+            this(type, vectorCoercion, preserveNames, preserveDimensions, preserveAttributes, true, null);
         }
 
-        public CoercionStep(RType type, boolean vectorCoercion, boolean preserveNames, boolean preserveDimensions, boolean preserveAttributes, boolean preserveNonVector) {
+        public CoercionStep(RType type, boolean vectorCoercion, boolean preserveNames, boolean preserveDimensions, boolean preserveAttributes, boolean preserveNonVector, RBaseNode messageCallObj) {
             this.type = type;
             this.vectorCoercion = vectorCoercion;
             this.preserveNames = preserveNames;
             this.preserveAttributes = preserveAttributes;
             this.preserveDimensions = preserveDimensions;
             this.preserveNonVector = preserveNonVector;
+            this.messageCallObj = messageCallObj;
         }
 
         public RType getType() {
             return type;
         }
 
+        public RBaseNode getMessageCallObj() {
+            return messageCallObj;
+        }
+
         @Override
         public <D> D accept(PipelineStepVisitor<D> visitor) {
             return visitor.visit(this);
diff --git a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/builtin/casts/PipelineToCastNode.java b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/builtin/casts/PipelineToCastNode.java
index 6d99e4f2ed1c49459477b97f0919038459544fc6..09f6591a27fa2cbd11199422f7f26241eca7043a 100644
--- a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/builtin/casts/PipelineToCastNode.java
+++ b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/builtin/casts/PipelineToCastNode.java
@@ -420,19 +420,19 @@ public final class PipelineToCastNode {
             RType type = step.getType();
             switch (type) {
                 case Integer:
-                    return step.vectorCoercion ? CastIntegerNodeGen.create(step.preserveNames, step.preserveDimensions, step.preserveAttributes)
-                                    : CastIntegerBaseNodeGen.create(step.preserveNames, step.preserveDimensions, step.preserveAttributes);
+                    return step.vectorCoercion ? CastIntegerNodeGen.create(step.preserveNames, step.preserveDimensions, step.preserveAttributes, step.getMessageCallObj())
+                                    : CastIntegerBaseNodeGen.create(step.preserveNames, step.preserveDimensions, step.preserveAttributes, step.getMessageCallObj());
                 case Double:
-                    return step.vectorCoercion ? CastDoubleNodeGen.create(step.preserveNames, step.preserveDimensions, step.preserveAttributes)
-                                    : CastDoubleBaseNodeGen.create(step.preserveNames, step.preserveDimensions, step.preserveAttributes);
+                    return step.vectorCoercion ? CastDoubleNodeGen.create(step.preserveNames, step.preserveDimensions, step.preserveAttributes, step.getMessageCallObj())
+                                    : CastDoubleBaseNodeGen.create(step.preserveNames, step.preserveDimensions, step.preserveAttributes, step.getMessageCallObj());
                 case Character:
                     return step.vectorCoercion ? CastStringNodeGen.create(step.preserveNames, step.preserveDimensions, step.preserveAttributes)
                                     : CastStringBaseNodeGen.create(step.preserveNames, step.preserveDimensions, step.preserveAttributes);
                 case Logical:
-                    return step.vectorCoercion ? CastLogicalNodeGen.create(step.preserveNames, step.preserveDimensions, step.preserveAttributes)
-                                    : CastLogicalBaseNodeGen.create(step.preserveNames, step.preserveDimensions, step.preserveAttributes);
+                    return step.vectorCoercion ? CastLogicalNodeGen.create(step.preserveNames, step.preserveDimensions, step.preserveAttributes, step.getMessageCallObj())
+                                    : CastLogicalBaseNodeGen.create(step.preserveNames, step.preserveDimensions, step.preserveAttributes, step.getMessageCallObj());
                 case Complex:
-                    return CastComplexNodeGen.create(step.preserveNames, step.preserveDimensions, step.preserveAttributes);
+                    return CastComplexNodeGen.create(step.preserveNames, step.preserveDimensions, step.preserveAttributes, step.getMessageCallObj());
                 case Raw:
                     return CastRawNodeGen.create(step.preserveNames, step.preserveDimensions, step.preserveAttributes);
                 case Any:
diff --git a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/builtin/casts/analysis/ForwardingAnalysisResult.java b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/builtin/casts/analysis/ForwardingAnalysisResult.java
index 34c20fe18ab200a430ae95e695e47ab768b24bf0..353156736aef1612b6b8550f02327fc8dd858969 100644
--- a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/builtin/casts/analysis/ForwardingAnalysisResult.java
+++ b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/builtin/casts/analysis/ForwardingAnalysisResult.java
@@ -151,6 +151,15 @@ public final class ForwardingAnalysisResult {
                             nullForwarded,
                             missingForwarded,
                             invalid);
+        } else if (Object.class == tp) {
+            return new ForwardingAnalysisResult(FORWARDED,
+                            FORWARDED,
+                            FORWARDED,
+                            FORWARDED,
+                            FORWARDED,
+                            FORWARDED,
+                            FORWARDED,
+                            invalid);
         } else {
             return this;
         }
diff --git a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/builtin/casts/fluent/InitialPhaseBuilder.java b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/builtin/casts/fluent/InitialPhaseBuilder.java
index 68a83118a1b306d41b8664e9ceb6ba92f4069296..58fe88bbdc18017e032a9af5d292c7a4e705dc6a 100644
--- a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/builtin/casts/fluent/InitialPhaseBuilder.java
+++ b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/builtin/casts/fluent/InitialPhaseBuilder.java
@@ -34,6 +34,7 @@ import com.oracle.truffle.r.runtime.data.RRaw;
 import com.oracle.truffle.r.runtime.data.model.RAbstractComplexVector;
 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.RAbstractLogicalVector;
 import com.oracle.truffle.r.runtime.data.model.RAbstractRawVector;
 import com.oracle.truffle.r.runtime.data.model.RAbstractStringVector;
 import com.oracle.truffle.r.runtime.data.model.RAbstractVector;
@@ -174,29 +175,53 @@ public class InitialPhaseBuilder<T> extends ArgCastBuilder<T, InitialPhaseBuilde
     }
 
     public CoercedPhaseBuilder<RAbstractIntVector, Integer> asIntegerVector(boolean preserveNames, boolean preserveDimensions, boolean preserveAttributes) {
-        pipelineBuilder().appendAsVector(RType.Integer, preserveNames, preserveDimensions, preserveAttributes);
+        return asIntegerVector(preserveNames, preserveDimensions, preserveAttributes, null);
+    }
+
+    public CoercedPhaseBuilder<RAbstractIntVector, Integer> asIntegerVector(boolean preserveNames, boolean preserveDimensions, boolean preserveAttributes, RBaseNode messageCallerObj) {
+        pipelineBuilder().appendAsVector(RType.Integer, preserveNames, preserveDimensions, preserveAttributes, messageCallerObj);
         return new CoercedPhaseBuilder<>(pipelineBuilder(), Integer.class);
     }
 
+    public CoercedPhaseBuilder<RAbstractIntVector, Integer> asIntegerVector(RBaseNode messageCallerObj) {
+        return asIntegerVector(false, false, false, messageCallerObj);
+    }
+
     public CoercedPhaseBuilder<RAbstractIntVector, Integer> asIntegerVector() {
         return asIntegerVector(false, false, false);
     }
 
     public CoercedPhaseBuilder<RAbstractDoubleVector, Double> asDoubleVector(boolean preserveNames, boolean preserveDimensions, boolean preserveAttributes) {
-        pipelineBuilder().appendAsVector(RType.Double, preserveNames, preserveDimensions, preserveAttributes);
+        return asDoubleVector(preserveNames, preserveDimensions, preserveAttributes, null);
+    }
+
+    public CoercedPhaseBuilder<RAbstractDoubleVector, Double> asDoubleVector(boolean preserveNames, boolean preserveDimensions, boolean preserveAttributes, RBaseNode messageCallerObj) {
+        pipelineBuilder().appendAsVector(RType.Double, preserveNames, preserveDimensions, preserveAttributes, messageCallerObj);
         return new CoercedPhaseBuilder<>(pipelineBuilder(), Double.class);
     }
 
+    public CoercedPhaseBuilder<RAbstractDoubleVector, Double> asDoubleVector(RBaseNode messageCallerObj) {
+        return asDoubleVector(false, false, false, messageCallerObj);
+    }
+
     public CoercedPhaseBuilder<RAbstractDoubleVector, Double> asDoubleVector() {
         return asDoubleVector(false, false, false);
     }
 
-    public CoercedPhaseBuilder<RAbstractDoubleVector, Byte> asLogicalVector(boolean preserveNames, boolean preserveDimensions, boolean preserveAttributes) {
-        pipelineBuilder().appendAsVector(RType.Logical, preserveNames, preserveDimensions, preserveAttributes);
+    public CoercedPhaseBuilder<RAbstractLogicalVector, Byte> asLogicalVector(boolean preserveNames, boolean preserveDimensions, boolean preserveAttributes, RBaseNode messageCallerObj) {
+        pipelineBuilder().appendAsVector(RType.Logical, preserveNames, preserveDimensions, preserveAttributes, messageCallerObj);
         return new CoercedPhaseBuilder<>(pipelineBuilder(), Byte.class);
     }
 
-    public CoercedPhaseBuilder<RAbstractDoubleVector, Byte> asLogicalVector() {
+    public CoercedPhaseBuilder<RAbstractLogicalVector, Byte> asLogicalVector(boolean preserveNames, boolean preserveDimensions, boolean preserveAttributes) {
+        return asLogicalVector(preserveNames, preserveDimensions, preserveAttributes, null);
+    }
+
+    public CoercedPhaseBuilder<RAbstractLogicalVector, Byte> asLogicalVector(RBaseNode messageCallerObj) {
+        return asLogicalVector(false, false, false, messageCallerObj);
+    }
+
+    public CoercedPhaseBuilder<RAbstractLogicalVector, Byte> asLogicalVector() {
         return asLogicalVector(false, false, false);
     }
 
@@ -210,10 +235,18 @@ public class InitialPhaseBuilder<T> extends ArgCastBuilder<T, InitialPhaseBuilde
     }
 
     public CoercedPhaseBuilder<RAbstractComplexVector, RComplex> asComplexVector(boolean preserveNames, boolean preserveDimensions, boolean preserveAttributes) {
-        pipelineBuilder().appendAsVector(RType.Complex, preserveNames, preserveDimensions, preserveAttributes);
+        return asComplexVector(preserveNames, preserveDimensions, preserveAttributes, null);
+    }
+
+    public CoercedPhaseBuilder<RAbstractComplexVector, RComplex> asComplexVector(boolean preserveNames, boolean preserveDimensions, boolean preserveAttributes, RBaseNode messageCallerObj) {
+        pipelineBuilder().appendAsVector(RType.Complex, preserveNames, preserveDimensions, preserveAttributes, messageCallerObj);
         return new CoercedPhaseBuilder<>(pipelineBuilder(), RComplex.class);
     }
 
+    public CoercedPhaseBuilder<RAbstractComplexVector, RComplex> asComplexVector(RBaseNode messageCallerObj) {
+        return asComplexVector(false, false, false, messageCallerObj);
+    }
+
     public CoercedPhaseBuilder<RAbstractComplexVector, RComplex> asComplexVector() {
         return asComplexVector(false, false, false);
     }
@@ -228,17 +261,17 @@ public class InitialPhaseBuilder<T> extends ArgCastBuilder<T, InitialPhaseBuilde
     }
 
     public CoercedPhaseBuilder<RAbstractVector, Object> asVector() {
-        pipelineBuilder().appendAsVector(false, false, false, true);
+        pipelineBuilder().appendAsVector(false, false, false, true, null);
         return new CoercedPhaseBuilder<>(pipelineBuilder(), Object.class);
     }
 
     public CoercedPhaseBuilder<RAbstractVector, Object> asVector(boolean preserveNonVector) {
-        pipelineBuilder().appendAsVector(false, false, false, preserveNonVector);
+        pipelineBuilder().appendAsVector(false, false, false, preserveNonVector, null);
         return new CoercedPhaseBuilder<>(pipelineBuilder(), Object.class);
     }
 
     public CoercedPhaseBuilder<RAbstractVector, Object> asVectorPreserveAttrs(boolean preserveNonVector) {
-        pipelineBuilder().appendAsVector(false, false, true, preserveNonVector);
+        pipelineBuilder().appendAsVector(false, false, true, preserveNonVector, null);
         return new CoercedPhaseBuilder<>(pipelineBuilder(), Object.class);
     }
 
diff --git a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/builtin/casts/fluent/PipelineBuilder.java b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/builtin/casts/fluent/PipelineBuilder.java
index b660585cb25644ca80ecff4b560c01519147bdcd..c5f4ba8394fb5725330bde49bc658ff886910af8 100644
--- a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/builtin/casts/fluent/PipelineBuilder.java
+++ b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/builtin/casts/fluent/PipelineBuilder.java
@@ -25,7 +25,6 @@ package com.oracle.truffle.r.nodes.builtin.casts.fluent;
 import java.util.Optional;
 import java.util.concurrent.atomic.AtomicReference;
 
-import com.oracle.truffle.r.nodes.builtin.CastBuilder;
 import com.oracle.truffle.r.nodes.builtin.casts.Filter;
 import com.oracle.truffle.r.nodes.builtin.casts.Mapper;
 import com.oracle.truffle.r.nodes.builtin.casts.MessageData;
@@ -39,9 +38,9 @@ import com.oracle.truffle.r.nodes.builtin.casts.PipelineStep.FindFirstStep;
 import com.oracle.truffle.r.nodes.builtin.casts.PipelineStep.MapIfStep;
 import com.oracle.truffle.r.nodes.builtin.casts.PipelineStep.MapStep;
 import com.oracle.truffle.r.nodes.builtin.casts.PipelineStep.NotNAStep;
+import com.oracle.truffle.r.nodes.builtin.casts.PipelineToCastNode;
 import com.oracle.truffle.r.nodes.builtin.casts.analysis.ForwardedValuesAnalyser;
 import com.oracle.truffle.r.nodes.builtin.casts.analysis.ForwardingAnalysisResult;
-import com.oracle.truffle.r.nodes.builtin.casts.PipelineToCastNode;
 import com.oracle.truffle.r.nodes.unary.CastNode;
 import com.oracle.truffle.r.runtime.RError.Message;
 import com.oracle.truffle.r.runtime.RType;
@@ -82,13 +81,17 @@ public final class PipelineBuilder {
         append(new AttributableCoercionStep<>(preserveNames, preserveDimensions, preserveAttributes));
     }
 
-    public void appendAsVector(boolean preserveNames, boolean preserveDimensions, boolean preserveAttributes, boolean preserveNonVector) {
-        append(new CoercionStep<>(RType.Any, true, preserveNames, preserveDimensions, preserveAttributes, preserveNonVector));
+    public void appendAsVector(boolean preserveNames, boolean preserveDimensions, boolean preserveAttributes, boolean preserveNonVector, RBaseNode messageCallerObj) {
+        append(new CoercionStep<>(RType.Any, true, preserveNames, preserveDimensions, preserveAttributes, preserveNonVector, messageCallerObj));
     }
 
-    public void appendAsVector(RType type, boolean preserveNames, boolean preserveDimensions, boolean preserveAttributes) {
+    public void appendAsVector(RType type, boolean preserveNames, boolean preserveDimensions, boolean preserveAttributes, RBaseNode messageCallerObj) {
         assert type == RType.Integer || type == RType.Double || type == RType.Complex || type == RType.Character || type == RType.Logical || type == RType.Raw;
-        append(new CoercionStep<>(type, true, preserveNames, preserveDimensions, preserveAttributes));
+        append(new CoercionStep<>(type, true, preserveNames, preserveDimensions, preserveAttributes, true, messageCallerObj));
+    }
+
+    public void appendAsVector(RType type, boolean preserveNames, boolean preserveDimensions, boolean preserveAttributes) {
+        appendAsVector(type, preserveNames, preserveDimensions, preserveAttributes, null);
     }
 
     public void appendNotNA(Object naReplacement, RBaseNode callObj, Message message, Object[] messageArgs) {
diff --git a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/unary/CastBaseNode.java b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/unary/CastBaseNode.java
index 860e6461885dec3ed983f115cc5e3e2b81ca9abe..1f77dc7c613660b33bcffd08b683c933095c681c 100644
--- a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/unary/CastBaseNode.java
+++ b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/unary/CastBaseNode.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2013, 2016, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2013, 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
@@ -43,6 +43,7 @@ import com.oracle.truffle.r.runtime.data.RTypedValue;
 import com.oracle.truffle.r.runtime.data.RVector;
 import com.oracle.truffle.r.runtime.data.model.RAbstractContainer;
 import com.oracle.truffle.r.runtime.env.REnvironment;
+import com.oracle.truffle.r.runtime.nodes.RBaseNode;
 
 public abstract class CastBaseNode extends CastNode {
 
@@ -59,13 +60,20 @@ public abstract class CastBaseNode extends CastNode {
     private final boolean preserveDimensions;
     private final boolean preserveAttributes;
 
-    protected CastBaseNode(boolean preserveNames, boolean preserveDimensions, boolean preserveAttributes) {
+    protected final RBaseNode messageCallObj;
+
+    protected CastBaseNode(boolean preserveNames, boolean preserveDimensions, boolean preserveAttributes, RBaseNode messageCallObj) {
         this.preserveNames = preserveNames;
         this.preserveDimensions = preserveDimensions;
         this.preserveAttributes = preserveAttributes;
         if (preserveDimensions) {
             getDimNamesNode = GetDimNamesAttributeNode.create();
         }
+        this.messageCallObj = messageCallObj == null ? this : messageCallObj;
+    }
+
+    protected CastBaseNode(boolean preserveNames, boolean preserveDimensions, boolean preserveAttributes) {
+        this(preserveNames, preserveDimensions, preserveAttributes, null);
     }
 
     public boolean preserveNames() {
@@ -84,7 +92,7 @@ public abstract class CastBaseNode extends CastNode {
 
     protected RError throwCannotCoerceListError(String type) {
         listCoercionErrorBranch.enter();
-        throw RError.error(this, RError.Message.LIST_COERCION, type);
+        throw RError.error(messageCallObj, RError.Message.LIST_COERCION, type);
     }
 
     protected int[] getPreservedDimensions(RAbstractContainer operand) {
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 00a0678e90084e096d056dc9b8e8d2ec4cb8a1c0..ac4c7257d26522de101146488e754c19913f92b2 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
@@ -45,6 +45,7 @@ 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.RAbstractListVector;
 import com.oracle.truffle.r.runtime.data.model.RAbstractVector;
+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;
 
@@ -62,6 +63,10 @@ public abstract class CastComplexNode extends CastBaseNode {
 
     public abstract Object executeComplex(Object o);
 
+    protected CastComplexNode(boolean preserveNames, boolean preserveDimensions, boolean preserveAttributes, RBaseNode messageCallerObj) {
+        super(preserveNames, preserveDimensions, preserveAttributes, messageCallerObj);
+    }
+
     protected CastComplexNode(boolean preserveNames, boolean preserveDimensions, boolean preserveAttributes) {
         super(preserveNames, preserveDimensions, preserveAttributes);
     }
diff --git a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/unary/CastDoubleBaseNode.java b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/unary/CastDoubleBaseNode.java
index 86b4afa0308aa0ee8ff456edba298987dab7a23c..eee5c3293436bdff45e3c16553e2514390029638 100644
--- a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/unary/CastDoubleBaseNode.java
+++ b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/unary/CastDoubleBaseNode.java
@@ -33,6 +33,7 @@ import com.oracle.truffle.r.runtime.data.RComplex;
 import com.oracle.truffle.r.runtime.data.RMissing;
 import com.oracle.truffle.r.runtime.data.RNull;
 import com.oracle.truffle.r.runtime.data.RRaw;
+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;
 
@@ -42,8 +43,12 @@ public abstract class CastDoubleBaseNode extends CastBaseNode {
     protected final NAProfile naProfile = NAProfile.create();
     protected final BranchProfile warningBranch = BranchProfile.create();
 
+    protected CastDoubleBaseNode(boolean preserveNames, boolean preserveDimensions, boolean preserveAttributes, RBaseNode messageCallObj) {
+        super(preserveNames, preserveDimensions, preserveAttributes, messageCallObj);
+    }
+
     protected CastDoubleBaseNode(boolean preserveNames, boolean preserveDimensions, boolean preserveAttributes) {
-        super(preserveNames, preserveDimensions, preserveAttributes);
+        this(preserveNames, preserveDimensions, preserveAttributes, null);
     }
 
     @Override
@@ -86,7 +91,7 @@ public abstract class CastDoubleBaseNode extends CastBaseNode {
         double result = naCheck.convertComplexToDouble(operand, false);
         if (operand.getImaginaryPart() != 0.0) {
             warningBranch.enter();
-            RError.warning(this, RError.Message.IMAGINARY_PARTS_DISCARDED_IN_COERCION);
+            RError.warning(messageCallObj, RError.Message.IMAGINARY_PARTS_DISCARDED_IN_COERCION);
         }
         return result;
     }
@@ -106,7 +111,7 @@ public abstract class CastDoubleBaseNode extends CastBaseNode {
         double result = RRuntime.string2doubleNoCheck(operand);
         if (RRuntime.isNA(result)) {
             warningBranch.enter();
-            RError.warning(this, RError.Message.NA_INTRODUCED_COERCION);
+            RError.warning(messageCallObj, RError.Message.NA_INTRODUCED_COERCION);
         }
         return result;
     }
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 497b3d09277ed57c7bac6b5e1062a25c30c2a2ac..3b98bd3901d57968edc1e6e58e68b6d60ad8f9e5 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
@@ -43,6 +43,7 @@ import com.oracle.truffle.r.runtime.data.model.RAbstractIntVector;
 import com.oracle.truffle.r.runtime.data.model.RAbstractListVector;
 import com.oracle.truffle.r.runtime.data.model.RAbstractLogicalVector;
 import com.oracle.truffle.r.runtime.data.model.RAbstractVector;
+import com.oracle.truffle.r.runtime.nodes.RBaseNode;
 
 public abstract class CastDoubleNode extends CastDoubleBaseNode {
 
@@ -50,6 +51,10 @@ public abstract class CastDoubleNode extends CastDoubleBaseNode {
         super(preserveNames, preserveDimensions, preserveAttributes);
     }
 
+    protected CastDoubleNode(boolean preserveNames, boolean preserveDimensions, boolean preserveAttributes, RBaseNode messageCallerObj) {
+        super(preserveNames, preserveDimensions, preserveAttributes, messageCallerObj);
+    }
+
     @Child private CastDoubleNode recursiveCastDouble;
 
     private Object castDoubleRecursive(Object o) {
@@ -117,7 +122,7 @@ public abstract class CastDoubleNode extends CastDoubleBaseNode {
             ddata[i] = doubleValue;
         }
         if (warning) {
-            RError.warning(this, RError.Message.NA_INTRODUCED_COERCION);
+            RError.warning(messageCallObj, RError.Message.NA_INTRODUCED_COERCION);
         }
         RDoubleVector ret = RDataFactory.createDoubleVector(ddata, !seenNA, getPreservedDimensions(operand), getPreservedNames(operand));
         preserveDimensionNames(operand, ret);
@@ -141,7 +146,7 @@ public abstract class CastDoubleNode extends CastDoubleBaseNode {
         }
         if (warning) {
             warningBranch.enter();
-            RError.warning(this, RError.Message.IMAGINARY_PARTS_DISCARDED_IN_COERCION);
+            RError.warning(messageCallObj, RError.Message.IMAGINARY_PARTS_DISCARDED_IN_COERCION);
         }
         return vectorCopy(operand, ddata, naCheck.neverSeenNA());
     }
diff --git a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/unary/CastIntegerBaseNode.java b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/unary/CastIntegerBaseNode.java
index 9f715e3836e42e393e5f342e825b9f9dd7e6fa3a..14766f8e64420a3718be737713643cef99cd92e6 100644
--- a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/unary/CastIntegerBaseNode.java
+++ b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/unary/CastIntegerBaseNode.java
@@ -34,6 +34,7 @@ import com.oracle.truffle.r.runtime.data.RComplex;
 import com.oracle.truffle.r.runtime.data.RMissing;
 import com.oracle.truffle.r.runtime.data.RNull;
 import com.oracle.truffle.r.runtime.data.RRaw;
+import com.oracle.truffle.r.runtime.nodes.RBaseNode;
 import com.oracle.truffle.r.runtime.ops.na.NACheck;
 
 public abstract class CastIntegerBaseNode extends CastBaseNode {
@@ -47,6 +48,10 @@ public abstract class CastIntegerBaseNode extends CastBaseNode {
         super(preserveNames, preserveDimensions, preserveAttributes);
     }
 
+    protected CastIntegerBaseNode(boolean preserveNames, boolean preserveDimensions, boolean preserveAttributes, RBaseNode messageCallObj) {
+        super(preserveNames, preserveDimensions, preserveAttributes, messageCallObj);
+    }
+
     @Override
     protected final RType getTargetType() {
         return RType.Integer;
@@ -55,7 +60,7 @@ public abstract class CastIntegerBaseNode extends CastBaseNode {
     protected Object castIntegerRecursive(Object o) {
         if (recursiveCastInteger == null) {
             CompilerDirectives.transferToInterpreterAndInvalidate();
-            recursiveCastInteger = insert(CastIntegerNodeGen.create(preserveNames(), preserveDimensions(), preserveAttributes()));
+            recursiveCastInteger = insert(CastIntegerNodeGen.create(preserveNames(), preserveDimensions(), preserveAttributes(), messageCallObj));
         }
         return recursiveCastInteger.executeInt(o);
     }
@@ -87,7 +92,7 @@ public abstract class CastIntegerBaseNode extends CastBaseNode {
         int result = naCheck.convertComplexToInt(operand, false);
         if (operand.getImaginaryPart() != 0.0) {
             warningBranch.enter();
-            RError.warning(this, RError.Message.IMAGINARY_PARTS_DISCARDED_IN_COERCION);
+            RError.warning(messageCallObj, RError.Message.IMAGINARY_PARTS_DISCARDED_IN_COERCION);
         }
         return result;
     }
@@ -102,7 +107,7 @@ public abstract class CastIntegerBaseNode extends CastBaseNode {
         int result = RRuntime.string2intNoCheck(operand);
         if (RRuntime.isNA(result)) {
             warningBranch.enter();
-            RError.warning(this, RError.Message.NA_INTRODUCED_COERCION);
+            RError.warning(messageCallObj, RError.Message.NA_INTRODUCED_COERCION);
         }
         return result;
     }
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 28966f1ed7f7e23a34f530cad207887c528ec2fd..796d7b556930f9690c2a5d9bc429ff7893c50836 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
@@ -42,6 +42,7 @@ import com.oracle.truffle.r.runtime.data.model.RAbstractLogicalVector;
 import com.oracle.truffle.r.runtime.data.model.RAbstractRawVector;
 import com.oracle.truffle.r.runtime.data.model.RAbstractStringVector;
 import com.oracle.truffle.r.runtime.data.model.RAbstractVector;
+import com.oracle.truffle.r.runtime.nodes.RBaseNode;
 import com.oracle.truffle.r.runtime.ops.na.NAProfile;
 
 public abstract class CastIntegerNode extends CastIntegerBaseNode {
@@ -52,6 +53,10 @@ public abstract class CastIntegerNode extends CastIntegerBaseNode {
         super(preserveNames, preserveDimensions, preserveAttributes);
     }
 
+    protected CastIntegerNode(boolean preserveNames, boolean preserveDimensions, boolean preserveAttributes, RBaseNode messageCallObj) {
+        super(preserveNames, preserveDimensions, preserveAttributes, messageCallObj);
+    }
+
     public abstract Object executeInt(int o);
 
     public abstract Object executeInt(double o);
@@ -118,7 +123,7 @@ public abstract class CastIntegerNode extends CastIntegerBaseNode {
         }
         if (warning) {
             warningBranch.enter();
-            RError.warning(this, RError.Message.IMAGINARY_PARTS_DISCARDED_IN_COERCION);
+            RError.warning(messageCallObj, RError.Message.IMAGINARY_PARTS_DISCARDED_IN_COERCION);
         }
         return vectorCopy(operand, idata, naCheck.neverSeenNA());
     }
@@ -149,7 +154,7 @@ public abstract class CastIntegerNode extends CastIntegerBaseNode {
             idata[i] = intValue;
         }
         if (warning) {
-            RError.warning(this, RError.Message.NA_INTRODUCED_COERCION);
+            RError.warning(messageCallObj, RError.Message.NA_INTRODUCED_COERCION);
         }
         return vectorCopy(operand, idata, !seenNA);
     }
@@ -221,14 +226,14 @@ public abstract class CastIntegerNode extends CastIntegerBaseNode {
     }
 
     public static CastIntegerNode create() {
-        return CastIntegerNodeGen.create(true, true, true);
+        return CastIntegerNodeGen.create(true, true, true, null);
     }
 
     public static CastIntegerNode createNonPreserving() {
-        return CastIntegerNodeGen.create(false, false, false);
+        return CastIntegerNodeGen.create(false, false, false, null);
     }
 
     public static CastIntegerNode createPreserveNames() {
-        return CastIntegerNodeGen.create(false, false, false);
+        return CastIntegerNodeGen.create(false, false, false, null);
     }
 }
diff --git a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/unary/CastLogicalBaseNode.java b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/unary/CastLogicalBaseNode.java
index 03ea9e3eb653978486ba62171af92fc0b7b962b2..d9883e2f08ea84986d3ad1116e6d93ed5f289a3f 100644
--- a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/unary/CastLogicalBaseNode.java
+++ b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/unary/CastLogicalBaseNode.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2015, 2016, Oracle and/or its affiliates. All rights reserved.
+ * 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
@@ -27,6 +27,7 @@ import com.oracle.truffle.r.runtime.RRuntime;
 import com.oracle.truffle.r.runtime.RType;
 import com.oracle.truffle.r.runtime.data.RComplex;
 import com.oracle.truffle.r.runtime.data.RRaw;
+import com.oracle.truffle.r.runtime.nodes.RBaseNode;
 import com.oracle.truffle.r.runtime.ops.na.NACheck;
 
 public abstract class CastLogicalBaseNode extends CastBaseNode {
@@ -37,6 +38,10 @@ public abstract class CastLogicalBaseNode extends CastBaseNode {
         super(preserveNames, preserveDimensions, preserveAttributes);
     }
 
+    protected CastLogicalBaseNode(boolean preserveNames, boolean preserveDimensions, boolean preserveAttributes, RBaseNode messageCallObj) {
+        super(preserveNames, preserveDimensions, preserveAttributes, messageCallObj);
+    }
+
     @Override
     protected final RType getTargetType() {
         return RType.Logical;
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 e104daf67ce2727daeda1dc5e8cc1c23a6febb88..7cd9f32a97fedbf623c582a520fdd697f49ff6bb 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
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2013, 2016, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2013, 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
@@ -41,6 +41,7 @@ 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.RAbstractListVector;
 import com.oracle.truffle.r.runtime.data.model.RAbstractVector;
+import com.oracle.truffle.r.runtime.nodes.RBaseNode;
 import com.oracle.truffle.r.runtime.ops.na.NAProfile;
 
 public abstract class CastLogicalNode extends CastLogicalBaseNode {
@@ -50,6 +51,10 @@ public abstract class CastLogicalNode extends CastLogicalBaseNode {
     @Child private CastLogicalNode recursiveCastLogical;
     @Child private InheritsCheckNode inheritsFactorCheck;
 
+    protected CastLogicalNode(boolean preserveNames, boolean preserveDimensions, boolean preserveAttributes, RBaseNode messageCallObj) {
+        super(preserveNames, preserveDimensions, preserveAttributes, messageCallObj);
+    }
+
     protected CastLogicalNode(boolean preserveNames, boolean preserveDimensions, boolean preserveAttributes) {
         super(preserveNames, preserveDimensions, preserveAttributes);
     }