diff --git a/src/main/java/com/typesafe/config/impl/AbstractConfigObject.java b/src/main/java/com/typesafe/config/impl/AbstractConfigObject.java
index c13e01c9..9c351c39 100644
--- a/src/main/java/com/typesafe/config/impl/AbstractConfigObject.java
+++ b/src/main/java/com/typesafe/config/impl/AbstractConfigObject.java
@@ -38,7 +38,7 @@ abstract class AbstractConfigObject extends AbstractConfigValue implements
     /**
      * Returns a version of this object that implements the ConfigRoot
      * interface.
-     * 
+     *
      * @return a config root
      */
     protected ConfigRoot asRoot() {
@@ -128,12 +128,15 @@ abstract class AbstractConfigObject extends AbstractConfigValue implements
 
     @Override
     AbstractConfigObject transformed(ConfigTransformer newTransformer) {
-        if (this.transformer != newTransformer)
-            return new TransformedConfigObject(newTransformer, this);
+        if (newTransformer != transformer)
+            return newCopy(newTransformer);
         else
             return this;
     }
 
+    protected abstract AbstractConfigObject newCopy(
+            ConfigTransformer newTransformer);
+
     static private AbstractConfigValue resolve(AbstractConfigObject self,
             String pathExpression,
             ConfigValueType expected, ConfigTransformer transformer,
diff --git a/src/main/java/com/typesafe/config/impl/ConfigDelayedMergeObject.java b/src/main/java/com/typesafe/config/impl/ConfigDelayedMergeObject.java
index ab8f4590..b3d98fd6 100644
--- a/src/main/java/com/typesafe/config/impl/ConfigDelayedMergeObject.java
+++ b/src/main/java/com/typesafe/config/impl/ConfigDelayedMergeObject.java
@@ -19,8 +19,9 @@ class ConfigDelayedMergeObject extends AbstractConfigObject implements
     final private List<AbstractConfigValue> stack;
 
     ConfigDelayedMergeObject(ConfigOrigin origin,
+            ConfigTransformer transformer,
             List<AbstractConfigValue> stack) {
-        super(origin);
+        super(origin, transformer);
         this.stack = stack;
         if (stack.isEmpty())
             throw new ConfigException.BugOrBroken(
@@ -30,6 +31,11 @@ class ConfigDelayedMergeObject extends AbstractConfigObject implements
                     "created a delayed merge object not guaranteed to be an object");
     }
 
+    ConfigDelayedMergeObject(ConfigOrigin origin,
+            List<AbstractConfigValue> stack) {
+        this(origin, ConfigImpl.defaultConfigTransformer(), stack);
+    }
+
     final private static class Root extends ConfigDelayedMergeObject implements
             ConfigRoot {
         Root(ConfigDelayedMergeObject original) {
@@ -57,6 +63,11 @@ class ConfigDelayedMergeObject extends AbstractConfigObject implements
         return new Root(this);
     }
 
+    @Override
+    public ConfigDelayedMergeObject newCopy(ConfigTransformer newTransformer) {
+        return new ConfigDelayedMergeObject(origin(), newTransformer, stack);
+    }
+
     @Override
     AbstractConfigObject resolveSubstitutions(SubstitutionResolver resolver,
             int depth, boolean withFallbacks) {
diff --git a/src/main/java/com/typesafe/config/impl/DelegatingConfigObject.java b/src/main/java/com/typesafe/config/impl/DelegatingConfigObject.java
index d5e0fb2c..243b175e 100644
--- a/src/main/java/com/typesafe/config/impl/DelegatingConfigObject.java
+++ b/src/main/java/com/typesafe/config/impl/DelegatingConfigObject.java
@@ -15,6 +15,18 @@ abstract class DelegatingConfigObject extends AbstractConfigObject {
         this.underlying = underlying;
     }
 
+    @Override
+    protected DelegatingConfigObject newCopy(ConfigTransformer newTransformer) {
+        AbstractConfigObject transformed = underlying
+                .transformed(newTransformer);
+        if (transformed != underlying)
+            return newCopy(transformed);
+        else
+            return this;
+    }
+
+    abstract DelegatingConfigObject newCopy(AbstractConfigObject underlying);
+
     @Override
     public boolean containsKey(Object key) {
         return underlying.containsKey(key);
diff --git a/src/main/java/com/typesafe/config/impl/RootConfigObject.java b/src/main/java/com/typesafe/config/impl/RootConfigObject.java
index 79c34bd5..9bb5194c 100644
--- a/src/main/java/com/typesafe/config/impl/RootConfigObject.java
+++ b/src/main/java/com/typesafe/config/impl/RootConfigObject.java
@@ -15,6 +15,11 @@ final class RootConfigObject extends DelegatingConfigObject implements
         return this;
     }
 
+    @Override
+    public RootConfigObject newCopy(AbstractConfigObject underlying) {
+        return new RootConfigObject(underlying);
+    }
+
     @Override
     public ConfigRoot resolve() {
         return ((AbstractConfigObject) SubstitutionResolver.resolve(this, this))
diff --git a/src/main/java/com/typesafe/config/impl/SimpleConfigObject.java b/src/main/java/com/typesafe/config/impl/SimpleConfigObject.java
index a82058fe..dc38e7fd 100644
--- a/src/main/java/com/typesafe/config/impl/SimpleConfigObject.java
+++ b/src/main/java/com/typesafe/config/impl/SimpleConfigObject.java
@@ -20,20 +20,30 @@ final class SimpleConfigObject extends AbstractConfigObject {
     // this map should never be modified - assume immutable
     final private Map<String, AbstractConfigValue> value;
 
-    SimpleConfigObject(ConfigOrigin origin,
+    SimpleConfigObject(ConfigOrigin origin, ConfigTransformer transformer,
             Map<String, AbstractConfigValue> value) {
-        super(origin);
+        super(origin, transformer);
         if (value == null)
             throw new ConfigException.BugOrBroken(
                     "creating config object with null map");
         this.value = value;
     }
 
+    SimpleConfigObject(ConfigOrigin origin,
+            Map<String, AbstractConfigValue> value) {
+        this(origin, ConfigImpl.defaultConfigTransformer(), value);
+    }
+
     @Override
     protected AbstractConfigValue peek(String key) {
         return value.get(key);
     }
 
+    @Override
+    public SimpleConfigObject newCopy(ConfigTransformer newTransformer) {
+        return new SimpleConfigObject(origin(), newTransformer, value);
+    }
+
     @Override
     public Map<String, Object> unwrapped() {
         Map<String, Object> m = new HashMap<String, Object>();
diff --git a/src/main/java/com/typesafe/config/impl/TransformedConfigObject.java b/src/main/java/com/typesafe/config/impl/TransformedConfigObject.java
deleted file mode 100644
index 59a6dfdf..00000000
--- a/src/main/java/com/typesafe/config/impl/TransformedConfigObject.java
+++ /dev/null
@@ -1,14 +0,0 @@
-package com.typesafe.config.impl;
-
-import com.typesafe.config.ConfigException;
-
-final class TransformedConfigObject extends DelegatingConfigObject {
-
-    TransformedConfigObject(ConfigTransformer transformer,
-            AbstractConfigObject underlying) {
-        super(transformer, underlying);
-        if (transformer == underlying.transformer)
-            throw new ConfigException.BugOrBroken(
-                    "Created unnecessary TransformedConfigObject");
-    }
-}