diff --git a/config/src/main/java/com/typesafe/config/impl/Parser.java b/config/src/main/java/com/typesafe/config/impl/Parser.java
index d9a27436..78a1b5c6 100644
--- a/config/src/main/java/com/typesafe/config/impl/Parser.java
+++ b/config/src/main/java/com/typesafe/config/impl/Parser.java
@@ -3,7 +3,10 @@
  */
 package com.typesafe.config.impl;
 
+import java.io.File;
 import java.io.StringReader;
+import java.net.MalformedURLException;
+import java.net.URL;
 import java.util.ArrayList;
 import java.util.Collections;
 import java.util.HashMap;
@@ -496,29 +499,87 @@ final class Parser {
                 t = nextTokenIgnoringNewline();
             }
 
-            if (Tokens.isValueWithType(t.token, ConfigValueType.STRING)) {
-                String name = (String) Tokens.getValue(t.token).unwrapped();
-                AbstractConfigObject obj = (AbstractConfigObject) includer
-                        .include(includeContext, name);
+            AbstractConfigObject obj;
 
-                if (!pathStack.isEmpty()) {
-                    Path prefix = new Path(pathStack);
-                    obj = obj.relativized(prefix);
+            // we either have a quoted string or the "file()" syntax
+            if (Tokens.isUnquotedText(t.token)) {
+                // get foo(
+                String kind = Tokens.getUnquotedText(t.token);
+
+                if (kind.equals("url(")) {
+
+                } else if (kind.equals("file(")) {
+
+                } else if (kind.equals("classpath(")) {
+
+                } else {
+                    throw parseError("expecting include parameter to be quoted filename, file(), classpath(), or url(). No spaces are allowed before the open paren. Not expecting: "
+                            + t);
                 }
 
-                for (String key : obj.keySet()) {
-                    AbstractConfigValue v = obj.get(key);
-                    AbstractConfigValue existing = values.get(key);
-                    if (existing != null) {
-                        values.put(key, v.withFallback(existing));
-                    } else {
-                        values.put(key, v);
+                // skip space inside parens
+                t = nextTokenIgnoringNewline();
+                while (isUnquotedWhitespace(t.token)) {
+                    t = nextTokenIgnoringNewline();
+                }
+
+                // quoted string
+                String name;
+                if (Tokens.isValueWithType(t.token, ConfigValueType.STRING)) {
+                    name = (String) Tokens.getValue(t.token).unwrapped();
+                } else {
+                    throw parseError("expecting a quoted string inside file(), classpath(), or url(), rather than: "
+                            + t);
+                }
+                // skip space after string, inside parens
+                t = nextTokenIgnoringNewline();
+                while (isUnquotedWhitespace(t.token)) {
+                    t = nextTokenIgnoringNewline();
+                }
+
+                if (Tokens.isUnquotedText(t.token) && Tokens.getUnquotedText(t.token).equals(")")) {
+                    // OK, close paren
+                } else {
+                    throw parseError("expecting a close parentheses ')' here, not: " + t);
+                }
+
+                if (kind.equals("url(")) {
+                    URL url;
+                    try {
+                        url = new URL(name);
+                    } catch (MalformedURLException e) {
+                        throw parseError("include url() specifies an invalid URL: " + name, e);
                     }
+                    obj = (AbstractConfigObject) includer.includeURL(includeContext, url);
+                } else if (kind.equals("file(")) {
+                    obj = (AbstractConfigObject) includer.includeFile(includeContext,
+                            new File(name));
+                } else if (kind.equals("classpath(")) {
+                    obj = (AbstractConfigObject) includer.includeResources(includeContext, name);
+                } else {
+                    throw new ConfigException.BugOrBroken("should not be reached");
                 }
-
+            } else if (Tokens.isValueWithType(t.token, ConfigValueType.STRING)) {
+                String name = (String) Tokens.getValue(t.token).unwrapped();
+                obj = (AbstractConfigObject) includer
+                        .include(includeContext, name);
             } else {
-                throw parseError("include keyword is not followed by a quoted string, but by: "
-                        + t);
+                throw parseError("include keyword is not followed by a quoted string, but by: " + t);
+            }
+
+            if (!pathStack.isEmpty()) {
+                Path prefix = new Path(pathStack);
+                obj = obj.relativized(prefix);
+            }
+
+            for (String key : obj.keySet()) {
+                AbstractConfigValue v = obj.get(key);
+                AbstractConfigValue existing = values.get(key);
+                if (existing != null) {
+                    values.put(key, v.withFallback(existing));
+                } else {
+                    values.put(key, v);
+                }
             }
         }
 
diff --git a/config/src/test/scala/com/typesafe/config/impl/ConfParserTest.scala b/config/src/test/scala/com/typesafe/config/impl/ConfParserTest.scala
index 6a8e37c5..2f954c53 100644
--- a/config/src/test/scala/com/typesafe/config/impl/ConfParserTest.scala
+++ b/config/src/test/scala/com/typesafe/config/impl/ConfParserTest.scala
@@ -489,4 +489,121 @@ class ConfParserTest extends TestUtils {
         assertComments(Seq(), conf8, "x")
         assertComments(Seq(), conf8, "a")
     }
+
+    @Test
+    def includeFile() {
+        val conf = ConfigFactory.parseString("include file(\"" + resourceFile("test01") + "\")")
+
+        // should have loaded conf, json, properties
+        assertEquals(42, conf.getInt("ints.fortyTwo"))
+        assertEquals(1, conf.getInt("fromJson1"))
+        assertEquals("abc", conf.getString("fromProps.abc"))
+    }
+
+    @Test
+    def includeFileWithExtension() {
+        val conf = ConfigFactory.parseString("include file(\"" + resourceFile("test01.conf") + "\")")
+
+        assertEquals(42, conf.getInt("ints.fortyTwo"))
+        assertFalse(conf.hasPath("fromJson1"))
+        assertFalse(conf.hasPath("fromProps.abc"))
+    }
+
+    @Test
+    def includeFileWhitespaceInsideParens() {
+        val conf = ConfigFactory.parseString("include file(  \n  \"" + resourceFile("test01") + "\"  \n  )")
+
+        // should have loaded conf, json, properties
+        assertEquals(42, conf.getInt("ints.fortyTwo"))
+        assertEquals(1, conf.getInt("fromJson1"))
+        assertEquals("abc", conf.getString("fromProps.abc"))
+    }
+
+    @Test
+    def includeFileNoWhitespaceOutsideParens() {
+        val e = intercept[ConfigException.Parse] {
+            ConfigFactory.parseString("include file (\"" + resourceFile("test01") + "\")")
+        }
+        assertTrue("wrong exception: " + e.getMessage, e.getMessage.contains("expecting include parameter"))
+    }
+
+    @Test
+    def includeFileNotQuoted() {
+        val e = intercept[ConfigException.Parse] {
+            ConfigFactory.parseString("include file(" + resourceFile("test01") + ")")
+        }
+        assertTrue("wrong exception: " + e.getMessage, e.getMessage.contains("expecting include parameter"))
+    }
+
+    @Test
+    def includeFileNotQuotedAndSpecialChar() {
+        val e = intercept[ConfigException.Parse] {
+            ConfigFactory.parseString("include file(:" + resourceFile("test01") + ")")
+        }
+        assertTrue("wrong exception: " + e.getMessage, e.getMessage.contains("expecting a quoted string"))
+    }
+
+    @Test
+    def includeFileUnclosedParens() {
+        val e = intercept[ConfigException.Parse] {
+            ConfigFactory.parseString("include file(\"" + resourceFile("test01") + "\" something")
+        }
+        assertTrue("wrong exception: " + e.getMessage, e.getMessage.contains("expecting a close paren"))
+    }
+
+    @Test
+    def includeURLBasename() {
+        // "AnySyntax" trick doesn't work for url() includes
+        val url = resourceFile("test01").toURI().toURL().toExternalForm()
+        val conf = ConfigFactory.parseString("include url(\"" + url + "\")")
+
+        assertTrue("including basename URL doesn't load anything", conf.isEmpty())
+    }
+
+    @Test
+    def includeURLWithExtension() {
+        val url = resourceFile("test01.conf").toURI().toURL().toExternalForm()
+        val conf = ConfigFactory.parseString("include url(\"" + url + "\")")
+
+        assertEquals(42, conf.getInt("ints.fortyTwo"))
+        assertFalse(conf.hasPath("fromJson1"))
+        assertFalse(conf.hasPath("fromProps.abc"))
+    }
+
+    @Test
+    def includeURLInvalid() {
+        val e = intercept[ConfigException.Parse] {
+            ConfigFactory.parseString("include url(\"junk:junk:junk\")")
+        }
+        assertTrue("wrong exception: " + e.getMessage, e.getMessage.contains("invalid URL"))
+    }
+
+    @Test
+    def includeResources() {
+        val conf = ConfigFactory.parseString("include classpath(\"test01\")")
+
+        // should have loaded conf, json, properties
+        assertEquals(42, conf.getInt("ints.fortyTwo"))
+        assertEquals(1, conf.getInt("fromJson1"))
+        assertEquals("abc", conf.getString("fromProps.abc"))
+    }
+
+    @Test
+    def includeURLHeuristically() {
+        val url = resourceFile("test01.conf").toURI().toURL().toExternalForm()
+        val conf = ConfigFactory.parseString("include \"" + url + "\"")
+
+        assertEquals(42, conf.getInt("ints.fortyTwo"))
+        assertFalse(conf.hasPath("fromJson1"))
+        assertFalse(conf.hasPath("fromProps.abc"))
+    }
+
+    @Test
+    def includeURLBasenameHeuristically() {
+        // "AnySyntax" trick doesn't work for url includes
+        val url = resourceFile("test01").toURI().toURL().toExternalForm()
+        val conf = ConfigFactory.parseString("include \"" + url + "\"")
+
+        assertTrue("including basename URL doesn't load anything", conf.isEmpty())
+    }
 }
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 c7af7f28..24aaa30b 100644
--- a/config/src/test/scala/com/typesafe/config/impl/PublicApiTest.scala
+++ b/config/src/test/scala/com/typesafe/config/impl/PublicApiTest.scala
@@ -13,6 +13,7 @@ import java.io.File
 import scala.collection.mutable
 import equiv03.SomethingInEquiv03
 import java.io.StringReader
+import java.net.URL
 
 class PublicApiTest extends TestUtils {
     @Test
@@ -282,11 +283,17 @@ class PublicApiTest extends TestUtils {
         assertEquals(conf, conf2)
     }
 
-    case class Included(name: String, fallback: ConfigIncluder)
+    sealed trait IncludeKind
+    case object IncludeKindHeuristic extends IncludeKind;
+    case object IncludeKindFile extends IncludeKind;
+    case object IncludeKindURL extends IncludeKind;
+    case object IncludeKindClasspath extends IncludeKind;
+
+    case class Included(name: String, fallback: ConfigIncluder, kind: IncludeKind)
 
     class RecordingIncluder(val fallback: ConfigIncluder, val included: mutable.ListBuffer[Included]) extends ConfigIncluder {
         override def include(context: ConfigIncludeContext, name: String): ConfigObject = {
-            included += Included(name, fallback)
+            included += Included(name, fallback, IncludeKindHeuristic)
             fallback.include(context, name)
         }
 
@@ -301,6 +308,35 @@ class PublicApiTest extends TestUtils {
         }
     }
 
+    class RecordingFullIncluder(fallback: ConfigIncluder, included: mutable.ListBuffer[Included])
+        extends RecordingIncluder(fallback, included)
+        with ConfigIncluderFile with ConfigIncluderURL with ConfigIncluderClasspath {
+        override def includeFile(context: ConfigIncludeContext, file: File) = {
+            included += Included("file(" + file.getName() + ")", fallback, IncludeKindFile)
+            fallback.asInstanceOf[ConfigIncluderFile].includeFile(context, file)
+        }
+
+        override def includeURL(context: ConfigIncludeContext, url: URL) = {
+            included += Included("url(" + url.toExternalForm() + ")", fallback, IncludeKindURL)
+            fallback.asInstanceOf[ConfigIncluderURL].includeURL(context, url)
+        }
+
+        override def includeResources(context: ConfigIncludeContext, name: String) = {
+            included += Included("classpath(" + name + ")", fallback, IncludeKindFile)
+            fallback.asInstanceOf[ConfigIncluderClasspath].includeResources(context, name)
+        }
+
+        override def withFallback(fallback: ConfigIncluder) = {
+            if (this.fallback == fallback) {
+                this;
+            } else if (this.fallback == null) {
+                new RecordingFullIncluder(fallback, included);
+            } else {
+                new RecordingFullIncluder(this.fallback.withFallback(fallback), included)
+            }
+        }
+    }
+
     private def whatWasIncluded(parser: ConfigParseOptions => Config): List[Included] = {
         val included = mutable.ListBuffer[Included]()
         val includer = new RecordingIncluder(null, included)
@@ -310,6 +346,15 @@ class PublicApiTest extends TestUtils {
         included.toList
     }
 
+    private def whatWasIncludedFull(parser: ConfigParseOptions => Config): List[Included] = {
+        val included = mutable.ListBuffer[Included]()
+        val includer = new RecordingFullIncluder(null, included)
+
+        val conf = parser(ConfigParseOptions.defaults().setIncluder(includer).setAllowMissing(false))
+
+        included.toList
+    }
+
     @Test
     def includersAreUsedWithFiles() {
         val included = whatWasIncluded(ConfigFactory.parseFile(resourceFile("test03.conf"), _))
@@ -337,6 +382,18 @@ class PublicApiTest extends TestUtils {
             included.map(_.name))
     }
 
+    // full includer should only be used with the file(), url(), classpath() syntax.
+    @Test
+    def fullIncluderNotUsedWithoutNewSyntax() {
+        val included = whatWasIncluded(ConfigFactory.parseFile(resourceFile("equiv03/includes.conf"), _))
+
+        assertEquals(List("letters/a.conf", "numbers/1.conf", "numbers/2", "letters/b.json", "letters/c", "root/foo.conf"),
+            included.map(_.name))
+
+        val includedFull = whatWasIncludedFull(ConfigFactory.parseFile(resourceFile("equiv03/includes.conf"), _))
+        assertEquals(included, includedFull)
+    }
+
     @Test
     def includersAreUsedWithClasspath() {
         val included = whatWasIncluded(ConfigFactory.parseResources(classOf[PublicApiTest], "/test03.conf", _))
@@ -377,6 +434,33 @@ class PublicApiTest extends TestUtils {
             included.map(_.name))
     }
 
+    @Test
+    def fullIncluderUsed() {
+        val included = whatWasIncludedFull(ConfigFactory.parseString("""
+                    include "equiv03/includes.conf"
+                    include file("nonexistent")
+                    include url("file:/nonexistent")
+                    include classpath("nonexistent")
+                """, _))
+        assertEquals(List("equiv03/includes.conf", "letters/a.conf", "numbers/1.conf",
+            "numbers/2", "letters/b.json", "letters/c", "root/foo.conf",
+            "file(nonexistent)", "url(file:/nonexistent)", "classpath(nonexistent)"),
+            included.map(_.name))
+    }
+
+    @Test
+    def nonFullIncluderSurvivesNewStyleIncludes() {
+        val included = whatWasIncluded(ConfigFactory.parseString("""
+                    include "equiv03/includes.conf"
+                    include file("nonexistent")
+                    include url("file:/nonexistent")
+                    include classpath("nonexistent")
+                """, _))
+        assertEquals(List("equiv03/includes.conf", "letters/a.conf", "numbers/1.conf",
+            "numbers/2", "letters/b.json", "letters/c", "root/foo.conf"),
+            included.map(_.name))
+    }
+
     @Test
     def stringParsing() {
         val conf = ConfigFactory.parseString("{ a : b }", ConfigParseOptions.defaults())