diff --git a/config/src/main/java/com/typesafe/config/ConfigList.java b/config/src/main/java/com/typesafe/config/ConfigList.java
index 5c694a50..01eca152 100644
--- a/config/src/main/java/com/typesafe/config/ConfigList.java
+++ b/config/src/main/java/com/typesafe/config/ConfigList.java
@@ -41,4 +41,6 @@ public interface ConfigList extends List<ConfigValue>, ConfigValue {
     @Override
     List<Object> unwrapped();
 
+    @Override
+    ConfigList withOrigin(ConfigOrigin origin);
 }
diff --git a/config/src/main/java/com/typesafe/config/ConfigObject.java b/config/src/main/java/com/typesafe/config/ConfigObject.java
index 76414edc..84583c79 100644
--- a/config/src/main/java/com/typesafe/config/ConfigObject.java
+++ b/config/src/main/java/com/typesafe/config/ConfigObject.java
@@ -129,4 +129,7 @@ public interface ConfigObject extends ConfigValue, Map<String, ConfigValue> {
      * @return the new instance with the new map entry
      */
     ConfigObject withValue(String key, ConfigValue value);
+    
+    @Override
+    ConfigObject withOrigin(ConfigOrigin origin);
 }
diff --git a/config/src/main/java/com/typesafe/config/ConfigOrigin.java b/config/src/main/java/com/typesafe/config/ConfigOrigin.java
index c34767fb..bc23898f 100644
--- a/config/src/main/java/com/typesafe/config/ConfigOrigin.java
+++ b/config/src/main/java/com/typesafe/config/ConfigOrigin.java
@@ -79,4 +79,36 @@ public interface ConfigOrigin {
      *         none
      */
     public List<String> comments();
+    
+    /**
+     * Returns a {@code ConfigOrigin} based on this one, but with the given
+     * comments. Does not modify this instance or any {@code ConfigValue}s with
+     * this origin (since they are immutable).  To set the returned origin to a 
+     * {@code ConfigValue}, use {@link ConfigValue#withOrigin}.
+     * 
+     * <p>
+     * Note that when the given comments are equal to the comments on this object,
+     * a new instance may not be created and {@code this} is returned directly.
+     * 
+     * @param comments the comments used on the returned origin
+     * @return the ConfigOrigin with the given comments
+     */
+    public ConfigOrigin withComments(List<String> comments);
+
+    /**
+     * Returns a {@code ConfigOrigin} based on this one, but with the given
+     * line number. This origin must be a FILE, URL or RESOURCE. Does not modify 
+     * this instance or any {@code ConfigValue}s with this origin (since they are
+     * immutable).  To set the returned origin to a  {@code ConfigValue}, use
+     * {@link ConfigValue#withOrigin}. 
+     * 
+     * <p>
+     * Note that when the given lineNumber are equal to the lineNumber on this
+     * object, a new instance may not be created and {@code this} is returned
+     * directly.
+     * 
+     * @param comments the comments used on the returned origin
+     * @return the created ConfigOrigin
+     */
+    public ConfigOrigin withLineNumber(int lineNumber);
 }
diff --git a/config/src/main/java/com/typesafe/config/ConfigOriginFactory.java b/config/src/main/java/com/typesafe/config/ConfigOriginFactory.java
new file mode 100644
index 00000000..86004f6e
--- /dev/null
+++ b/config/src/main/java/com/typesafe/config/ConfigOriginFactory.java
@@ -0,0 +1,59 @@
+package com.typesafe.config;
+
+import java.net.URL;
+
+import com.typesafe.config.impl.ConfigImpl;
+
+/**
+ * This class contains some static factory methods for building a {@link
+ * ConfigOrigin}. {@code ConfigOrigin}s are automatically created when you
+ * call other API methods to get a {@code ConfigValue} or {@code Config}.
+ * But you can also set the origin of an existing {@code ConfigValue}, using
+ * {@link ConfigValue#withOrigin(ConfigOrigin)}.
+ *
+ */
+public final class ConfigOriginFactory {
+    private ConfigOriginFactory() {
+    }
+    
+    /**
+     * Returns the default origin for values when no other information is
+     * provided. This is the origin used in {@link ConfigValueFactory
+     * #fromAnyRef(Object)}.
+     * 
+     * @return the default origin
+     */
+    public static ConfigOrigin newSimple() {
+        return newSimple(null);
+    }
+    
+    /**
+     * Returns a origin with the given description.
+     * 
+     * @param description brief description of what the origin is
+     * @return
+     */
+    public static ConfigOrigin newSimple(String description) {
+        return ConfigImpl.newSimpleOrigin(description);
+    }
+    
+    /**
+     * Creates a file origin with the given filename.
+     * 
+     * @param filename the filename of this origin
+     * @return
+     */
+    public static ConfigOrigin newFile(String filename) {
+        return ConfigImpl.newFileOrigin(filename);
+    }
+    
+    /**
+     * Creates a url origin with the given URL object.
+     * 
+     * @param url the url of this origin
+     * @return
+     */
+    public static ConfigOrigin newURL(URL url) {
+        return ConfigImpl.newURLOrigin(url);
+    }
+}
diff --git a/config/src/main/java/com/typesafe/config/ConfigValue.java b/config/src/main/java/com/typesafe/config/ConfigValue.java
index 35c40b8b..b5dc2411 100644
--- a/config/src/main/java/com/typesafe/config/ConfigValue.java
+++ b/config/src/main/java/com/typesafe/config/ConfigValue.java
@@ -106,4 +106,13 @@ public interface ConfigValue extends ConfigMergeable {
      * @return a {@code Config} instance containing this value at the given key.
      */
     Config atKey(String key);
+    
+    /**
+     * Returns a new {@code ConfigValue} based on this one, but with the given
+     * origin. This is useful  when you are parsing a new format of file or setting
+     * comments for a single ConfigValue.
+     * @param origin the origin set on the returned value
+     * @return the new ConfigValue with the given origin
+     */
+    ConfigValue withOrigin(ConfigOrigin origin);
 }
diff --git a/config/src/main/java/com/typesafe/config/impl/AbstractConfigObject.java b/config/src/main/java/com/typesafe/config/impl/AbstractConfigObject.java
index a6863672..a98515de 100644
--- a/config/src/main/java/com/typesafe/config/impl/AbstractConfigObject.java
+++ b/config/src/main/java/com/typesafe/config/impl/AbstractConfigObject.java
@@ -18,7 +18,6 @@ import com.typesafe.config.ConfigValue;
 import com.typesafe.config.ConfigValueType;
 
 abstract class AbstractConfigObject extends AbstractConfigValue implements ConfigObject, Container {
-
     final private SimpleConfig config;
 
     protected AbstractConfigObject(ConfigOrigin origin) {
@@ -214,4 +213,9 @@ abstract class AbstractConfigObject extends AbstractConfigValue implements Confi
     public ConfigValue remove(Object arg0) {
         throw weAreImmutable("remove");
     }
+
+    @Override
+    public AbstractConfigObject withOrigin(ConfigOrigin origin) {
+        return (AbstractConfigObject) super.withOrigin(origin);
+    }
 }
diff --git a/config/src/main/java/com/typesafe/config/impl/AbstractConfigValue.java b/config/src/main/java/com/typesafe/config/impl/AbstractConfigValue.java
index 0720417e..4c3dd5b2 100644
--- a/config/src/main/java/com/typesafe/config/impl/AbstractConfigValue.java
+++ b/config/src/main/java/com/typesafe/config/impl/AbstractConfigValue.java
@@ -257,6 +257,7 @@ abstract class AbstractConfigValue implements ConfigValue, MergeableValue {
         return mergedWithNonObject(Collections.singletonList(this), fallback);
     }
 
+    @Override
     public AbstractConfigValue withOrigin(ConfigOrigin origin) {
         if (this.origin == origin)
             return this;
diff --git a/config/src/main/java/com/typesafe/config/impl/ConfigImpl.java b/config/src/main/java/com/typesafe/config/impl/ConfigImpl.java
index d06b2c34..332a754d 100644
--- a/config/src/main/java/com/typesafe/config/impl/ConfigImpl.java
+++ b/config/src/main/java/com/typesafe/config/impl/ConfigImpl.java
@@ -5,6 +5,7 @@ package com.typesafe.config.impl;
 
 import java.io.File;
 import java.lang.ref.WeakReference;
+import java.net.URL;
 import java.util.ArrayList;
 import java.util.Collections;
 import java.util.HashMap;
@@ -461,4 +462,24 @@ public class ConfigImpl {
         else
             return new ConfigException.NotResolved(newMessage, original);
     }
+    
+    /** For use ONLY by library internals, DO NOT TOUCH not guaranteed ABI */
+    public static ConfigOrigin newSimpleOrigin(String description) {
+        if (description == null) {
+            return defaultValueOrigin;
+        } else {
+            return SimpleConfigOrigin.newSimple(description);
+        }
+    }
+
+    /** For use ONLY by library internals, DO NOT TOUCH not guaranteed ABI */
+    public static ConfigOrigin newFileOrigin(String filename) {
+        return SimpleConfigOrigin.newFile(filename);
+    }
+    
+    /** For use ONLY by library internals, DO NOT TOUCH not guaranteed ABI */
+    public static ConfigOrigin newURLOrigin(URL url) {
+        return SimpleConfigOrigin.newURL(url);
+    }
+    
 }
diff --git a/config/src/main/java/com/typesafe/config/impl/SimpleConfigList.java b/config/src/main/java/com/typesafe/config/impl/SimpleConfigList.java
index 49387177..57ea7af0 100644
--- a/config/src/main/java/com/typesafe/config/impl/SimpleConfigList.java
+++ b/config/src/main/java/com/typesafe/config/impl/SimpleConfigList.java
@@ -451,4 +451,9 @@ final class SimpleConfigList extends AbstractConfigValue implements ConfigList,
     private Object writeReplace() throws ObjectStreamException {
         return new SerializedConfigValue(this);
     }
+
+    @Override
+    public SimpleConfigList withOrigin(ConfigOrigin origin) {
+        return (SimpleConfigList) super.withOrigin(origin);
+    }
 }
diff --git a/config/src/main/java/com/typesafe/config/impl/SimpleConfigOrigin.java b/config/src/main/java/com/typesafe/config/impl/SimpleConfigOrigin.java
index 25bbae3e..6e275d34 100644
--- a/config/src/main/java/com/typesafe/config/impl/SimpleConfigOrigin.java
+++ b/config/src/main/java/com/typesafe/config/impl/SimpleConfigOrigin.java
@@ -550,4 +550,18 @@ final class SimpleConfigOrigin implements ConfigOrigin {
         Map<SerializedField, Object> fields = applyFieldsDelta(baseFields, delta);
         return fromFields(fields);
     }
+
+    @Override
+    public ConfigOrigin withComments(List<String> comments) {
+        return this.setComments(comments);
+    }
+
+    @Override
+    public ConfigOrigin withLineNumber(int lineNumber) {
+        if (this.originType == OriginType.GENERIC) {
+            //This type should not have a lineNumber.
+            throw new UnsupportedOperationException();
+        }
+        return this.setLineNumber(lineNumber);
+    }
 }