diff --git a/config/src/main/java/com/typesafe/config/ConfigFactory.java b/config/src/main/java/com/typesafe/config/ConfigFactory.java
index 8506552f..49cff71d 100644
--- a/config/src/main/java/com/typesafe/config/ConfigFactory.java
+++ b/config/src/main/java/com/typesafe/config/ConfigFactory.java
@@ -40,6 +40,12 @@ public final class ConfigFactory {
      * {@link Class#getResource}).
      *
      * <p>
+     * Resources are loaded from the current thread's
+     * {@link Thread#getContextClassLoader()}. In general, a library needs its
+     * configuration to come from the class loader used to load that library, so
+     * the proper "reference.conf" are present.
+     *
+     * <p>
      * The loaded object will already be resolved (substitutions have already
      * been processed). As a result, if you add more fallbacks then they won't
      * be seen by substitutions. Substitutions are the "${foo.bar}" syntax. If
@@ -48,16 +54,29 @@ public final class ConfigFactory {
      *
      * @param resourceBasename
      *            name (optionally without extension) of a resource on classpath
-     * @return configuration for an application
+     * @return configuration for an application relative to context class loader
      */
     public static Config load(String resourceBasename) {
-        return load(resourceBasename, ConfigParseOptions.defaults(),
+        return load(Thread.currentThread().getContextClassLoader(), resourceBasename);
+    }
+
+    /**
+     * Like {@link #load(String)} but uses the supplied class loader instead of
+     * the current thread's context class loader.
+     *
+     * @param loader
+     * @param resourceBasename
+     * @return configuration for an application relative to given class loader
+     */
+    public static Config load(ClassLoader loader, String resourceBasename) {
+        return load(loader, resourceBasename, ConfigParseOptions.defaults(),
                 ConfigResolveOptions.defaults());
     }
 
     /**
      * Like {@link #load(String)} but allows you to specify parse and resolve
      * options.
+     *
      * @param resourceBasename
      *            the classpath resource name with optional extension
      * @param parseOptions
@@ -68,9 +87,29 @@ public final class ConfigFactory {
      */
     public static Config load(String resourceBasename, ConfigParseOptions parseOptions,
             ConfigResolveOptions resolveOptions) {
-        Config appConfig = ConfigFactory.parseResourcesAnySyntax(ConfigFactory.class, "/"
-                + resourceBasename, parseOptions);
-        return load(appConfig, resolveOptions);
+        return load(Thread.currentThread().getContextClassLoader(), resourceBasename, parseOptions,
+                resolveOptions);
+    }
+
+    /**
+     * Like {@link #load(String,ConfigParseOptions,ConfigResolveOptions)} but
+     * allows you to specify a class loader
+     *
+     * @param loader
+     *            class loader in which to find resources
+     * @param resourceBasename
+     *            the classpath resource name with optional extension
+     * @param parseOptions
+     *            options to use when parsing the resource
+     * @param resolveOptions
+     *            options to use when resolving the stack
+     * @return configuration for an application
+     */
+    public static Config load(ClassLoader loader, String resourceBasename,
+            ConfigParseOptions parseOptions, ConfigResolveOptions resolveOptions) {
+        Config appConfig = ConfigFactory.parseResourcesAnySyntax(loader, resourceBasename,
+                parseOptions);
+        return load(loader, appConfig, resolveOptions);
     }
 
     /**
@@ -84,7 +123,11 @@ public final class ConfigFactory {
      * @return resolved configuration with overrides and fallbacks added
      */
     public static Config load(Config config) {
-        return load(config, ConfigResolveOptions.defaults());
+        return load(Thread.currentThread().getContextClassLoader(), config);
+    }
+
+    public static Config load(ClassLoader loader, Config config) {
+        return load(loader, config, ConfigResolveOptions.defaults());
     }
 
     /**
@@ -98,11 +141,28 @@ public final class ConfigFactory {
      * @return resolved configuration with overrides and fallbacks added
      */
     public static Config load(Config config, ConfigResolveOptions resolveOptions) {
-        return defaultOverrides().withFallback(config).withFallback(defaultReference())
+        return load(Thread.currentThread().getContextClassLoader(), config, resolveOptions);
+    }
+
+    /**
+     * Like {@link #load(Config,ConfigResolveOptions)} but allows you to specify
+     * a class loader other than the context class loader.
+     *
+     * @param loader
+     *            class loader to use when looking up override and reference
+     *            configs
+     * @param config
+     *            the application's portion of the configuration
+     * @param resolveOptions
+     *            options for resolving the assembled config stack
+     * @return resolved configuration with overrides and fallbacks added
+     */
+    public static Config load(ClassLoader loader, Config config, ConfigResolveOptions resolveOptions) {
+        return defaultOverrides(loader).withFallback(config).withFallback(defaultReference(loader))
                 .resolve(resolveOptions);
     }
 
-    private static Config loadDefaultConfig() {
+    private static Config loadDefaultConfig(ClassLoader loader) {
         int specified = 0;
 
         // override application.conf with config.file, config.resource,
@@ -118,7 +178,7 @@ public final class ConfigFactory {
             specified += 1;
 
         if (specified == 0) {
-            return load("application");
+            return load(loader, "application");
         } else if (specified > 1) {
             throw new ConfigException.Generic("You set more than one of config.file='" + file
                     + "', config.url='" + url + "', config.resource='" + resource
@@ -127,12 +187,12 @@ public final class ConfigFactory {
             if (resource != null) {
                 // this deliberately does not parseResourcesAnySyntax; if
                 // people want that they can use an include statement.
-                return load(parseResources(ConfigFactory.class, resource));
+                return load(loader, parseResources(loader, resource));
             } else if (file != null) {
-                return load(parseFile(new File(file)));
+                return load(loader, parseFile(new File(file)));
             } else {
                 try {
-                    return load(parseURL(new URL(url)));
+                    return load(loader, parseURL(new URL(url)));
                 } catch (MalformedURLException e) {
                     throw new ConfigException.Generic("Bad URL in config.url system property: '"
                             + url + "': " + e.getMessage(), e);
@@ -169,7 +229,19 @@ public final class ConfigFactory {
      * @return configuration for an application
      */
     public static Config load() {
-        return loadDefaultConfig();
+        return load(Thread.currentThread().getContextClassLoader());
+    }
+
+    /**
+     * Like {@link #load()} but allows specifying a class loader other than the
+     * thread's current context class loader.
+     *
+     * @param loader
+     *            class loader for finding resources
+     * @return configuration for an application
+     */
+    public static Config load(ClassLoader loader) {
+        return loadDefaultConfig(loader);
     }
 
     /**
@@ -183,6 +255,13 @@ public final class ConfigFactory {
      * jar.
      *
      * <p>
+     * The reference config must be looked up in the class loader that contains
+     * the libraries that you want to use with this config, so the
+     * "reference.conf" for each library can be found. Use
+     * {@link #defaultReference(ClassLoader)} if the context class loader is not
+     * suitable.
+     *
+     * <p>
      * The {@link #load()} methods merge this configuration for you
      * automatically.
      *
@@ -191,10 +270,21 @@ public final class ConfigFactory {
      * is not guaranteed that this method <em>only</em> looks at
      * "reference.conf".
      *
-     * @return the default reference config
+     * @return the default reference config for context class loader
      */
     public static Config defaultReference() {
-        return ConfigImpl.defaultReference();
+        return defaultReference(Thread.currentThread().getContextClassLoader());
+    }
+
+    /**
+     * Like {@link #defaultReference()} but allows you to specify a class loader
+     * to use rather than the current context class loader.
+     *
+     * @param loader
+     * @return the default reference config for this class loader
+     */
+    public static Config defaultReference(ClassLoader loader) {
+        return ConfigImpl.defaultReference(loader);
     }
 
     /**
@@ -216,6 +306,17 @@ public final class ConfigFactory {
         return systemProperties();
     }
 
+    /**
+     * Like {@link #defaultOverrides()} but allows you to specify a class loader
+     * to use rather than the current context class loader.
+     *
+     * @param loader
+     * @return the default override configuration
+     */
+    public static Config defaultOverrides(ClassLoader loader) {
+        return systemProperties();
+    }
+
     /**
      * Gets an empty configuration. See also {@link #empty(String)} to create an
      * empty configuration with a description, which may improve user-visible
@@ -454,6 +555,106 @@ public final class ConfigFactory {
         return parseResourcesAnySyntax(klass, resourceBasename, ConfigParseOptions.defaults());
     }
 
+    /**
+     * Parses all resources on the classpath with the given name and merges them
+     * into a single <code>Config</code>.
+     *
+     * <p>
+     * This works like {@link java.lang.ClassLoader#getResource}, not like
+     * {@link java.lang.Class#getResource}, so the name never begins with a
+     * slash.
+     *
+     * <p>
+     * See {@link #parseResources(Class,String,ConfigParseOptions)} for full
+     * details.
+     *
+     * @param loader
+     *            will be used to load resources
+     * @param resource
+     *            resource to look up
+     * @param options
+     *            parse options
+     * @return the parsed configuration
+     */
+    public static Config parseResources(ClassLoader loader, String resource,
+            ConfigParseOptions options) {
+        return Parseable.newResources(loader, resource, options).parse().toConfig();
+    }
+
+    public static Config parseResources(ClassLoader loader, String resource) {
+        return parseResources(loader, resource, ConfigParseOptions.defaults());
+    }
+
+    /**
+     * Parses classpath resources with a flexible extension. In general, this
+     * method has the same behavior as
+     * {@link #parseFileAnySyntax(File,ConfigParseOptions)} but for classpath
+     * resources instead, as in
+     * {@link #parseResources(ClassLoader,String,ConfigParseOptions)}.
+     *
+     * <p>
+     * {@link #parseResourcesAnySyntax(Class,String,ConfigParseOptions)} differs
+     * in the syntax for the resource name, but otherwise see
+     * {@link #parseResourcesAnySyntax(Class,String,ConfigParseOptions)} for
+     * some details and caveats on this method.
+     *
+     * @param loader
+     *            class loader to look up resources in
+     * @param resourceBasename
+     *            a resource name as in
+     *            {@link java.lang.ClassLoader#getResource}, with or without
+     *            extension
+     * @param options
+     *            parse options
+     * @return the parsed configuration
+     */
+    public static Config parseResourcesAnySyntax(ClassLoader loader, String resourceBasename,
+            ConfigParseOptions options) {
+        return ConfigImpl.parseResourcesAnySyntax(loader, resourceBasename, options).toConfig();
+    }
+
+    public static Config parseResourcesAnySyntax(ClassLoader loader, String resourceBasename) {
+        return parseResourcesAnySyntax(loader, resourceBasename, ConfigParseOptions.defaults());
+    }
+
+    /**
+     * Like {@link #parseResources(ClassLoader,String,ConfigParseOptions)} but
+     * uses thread's current context class loader.
+     */
+    public static Config parseResources(String resource, ConfigParseOptions options) {
+        return Parseable
+                .newResources(Thread.currentThread().getContextClassLoader(), resource, options)
+                .parse().toConfig();
+    }
+
+    /**
+     * Like {@link #parseResources(ClassLoader,String)} but uses thread's
+     * current context class loader.
+     */
+    public static Config parseResources(String resource) {
+        return parseResources(Thread.currentThread().getContextClassLoader(), resource,
+                ConfigParseOptions.defaults());
+    }
+
+    /**
+     * Like
+     * {@link #parseResourcesAnySyntax(ClassLoader,String,ConfigParseOptions)}
+     * but uses thread's current context class loader.
+     */
+    public static Config parseResourcesAnySyntax(String resourceBasename, ConfigParseOptions options) {
+        return ConfigImpl.parseResourcesAnySyntax(Thread.currentThread().getContextClassLoader(),
+                resourceBasename, options).toConfig();
+    }
+
+    /**
+     * Like {@link #parseResourcesAnySyntax(ClassLoader,String)} but uses
+     * thread's current context class loader.
+     */
+    public static Config parseResourcesAnySyntax(String resourceBasename) {
+        return parseResourcesAnySyntax(Thread.currentThread().getContextClassLoader(),
+                resourceBasename, ConfigParseOptions.defaults());
+    }
+
     public static Config parseString(String s, ConfigParseOptions options) {
         return Parseable.newString(s, options).parse().toConfig();
     }
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 583d2507..11d12909 100644
--- a/config/src/main/java/com/typesafe/config/impl/ConfigImpl.java
+++ b/config/src/main/java/com/typesafe/config/impl/ConfigImpl.java
@@ -118,6 +118,18 @@ public class ConfigImpl {
         return fromBasename(source, resourceBasename, baseOptions);
     }
 
+    /** For use ONLY by library internals, DO NOT TOUCH not guaranteed ABI */
+    public static ConfigObject parseResourcesAnySyntax(final ClassLoader loader,
+            String resourceBasename, final ConfigParseOptions baseOptions) {
+        NameSource source = new NameSource() {
+            @Override
+            public ConfigParseable nameToParseable(String name) {
+                return Parseable.newResources(loader, name, baseOptions);
+            }
+        };
+        return fromBasename(source, resourceBasename, baseOptions);
+    }
+
     /** For use ONLY by library internals, DO NOT TOUCH not guaranteed ABI */
     public static ConfigObject parseFileAnySyntax(final File basename,
             final ConfigParseOptions baseOptions) {
@@ -398,10 +410,10 @@ public class ConfigImpl {
     }
 
     /** For use ONLY by library internals, DO NOT TOUCH not guaranteed ABI */
-    public static Config defaultReference() {
+    public static Config defaultReference(ClassLoader loader) {
         Config unresolvedResources = Parseable
-                .newResources(Thread.currentThread().getContextClassLoader(), "reference.conf",
-                        ConfigParseOptions.defaults()).parse().toConfig();
+                .newResources(loader, "reference.conf", ConfigParseOptions.defaults()).parse()
+                .toConfig();
         return systemPropertiesAsConfig().withFallback(unresolvedResources).resolve();
     }
 
diff --git a/config/src/test/scala/com/typesafe/config/impl/PublicApiTest.scala b/config/src/test/scala/com/typesafe/config/impl/PublicApiTest.scala
index 2948d69f..e0a60e8a 100644
--- a/config/src/test/scala/com/typesafe/config/impl/PublicApiTest.scala
+++ b/config/src/test/scala/com/typesafe/config/impl/PublicApiTest.scala
@@ -488,4 +488,57 @@ class PublicApiTest extends TestUtils {
         assertFalse("no a", configPlain.hasPath("a"))
         assertFalse("no b", configPlain.hasPath("b"))
     }
+
+    @Test
+    def usesSuppliedClassLoader() {
+        val loaderA1 = new TestClassLoader(this.getClass().getClassLoader(),
+            Map("reference.conf" -> resourceFile("a_1.conf").toURI.toURL()))
+        val loaderB2 = new TestClassLoader(this.getClass().getClassLoader(),
+            Map("reference.conf" -> resourceFile("b_2.conf").toURI.toURL()))
+
+        val configA1 = ConfigFactory.load(loaderA1)
+
+        assertEquals(1, configA1.getInt("a"))
+        assertFalse("no b", configA1.hasPath("b"))
+
+        val configB2 = ConfigFactory.load(loaderB2)
+
+        assertEquals(2, configB2.getInt("b"))
+        assertFalse("no a", configB2.hasPath("a"))
+
+        val configPlain = ConfigFactory.load()
+        assertFalse("no a", configPlain.hasPath("a"))
+        assertFalse("no b", configPlain.hasPath("b"))
+
+        // check the various overloads that take a loader parameter
+        for (
+            c <- Seq(ConfigFactory.parseResources(loaderA1, "reference.conf"),
+                ConfigFactory.parseResourcesAnySyntax(loaderA1, "reference"),
+                ConfigFactory.parseResources(loaderA1, "reference.conf", ConfigParseOptions.defaults()),
+                ConfigFactory.parseResourcesAnySyntax(loaderA1, "reference", ConfigParseOptions.defaults()),
+                ConfigFactory.load(loaderA1, "application"),
+                ConfigFactory.load(loaderA1, "application", ConfigParseOptions.defaults(), ConfigResolveOptions.defaults()),
+                ConfigFactory.load(loaderA1, ConfigFactory.parseString("")),
+                ConfigFactory.load(loaderA1, ConfigFactory.parseString(""), ConfigResolveOptions.defaults()),
+                ConfigFactory.defaultReference(loaderA1))
+        ) {
+            assertEquals(1, c.getInt("a"))
+            assertFalse("no b", c.hasPath("b"))
+        }
+
+        for (
+            c <- Seq(ConfigFactory.parseResources("reference.conf"),
+                ConfigFactory.parseResourcesAnySyntax("reference"),
+                ConfigFactory.parseResources("reference.conf", ConfigParseOptions.defaults()),
+                ConfigFactory.parseResourcesAnySyntax("reference", ConfigParseOptions.defaults()),
+                ConfigFactory.load("application"),
+                ConfigFactory.load("application", ConfigParseOptions.defaults(), ConfigResolveOptions.defaults()),
+                ConfigFactory.load(ConfigFactory.parseString("")),
+                ConfigFactory.load(ConfigFactory.parseString(""), ConfigResolveOptions.defaults()),
+                ConfigFactory.defaultReference())
+        ) {
+            assertFalse("no a", c.hasPath("a"))
+            assertFalse("no b", c.hasPath("b"))
+        }
+    }
 }