diff --git a/src/main/java/com/typesafe/config/ConfigObject.java b/src/main/java/com/typesafe/config/ConfigObject.java
index 8ad71b99..21da5ae1 100644
--- a/src/main/java/com/typesafe/config/ConfigObject.java
+++ b/src/main/java/com/typesafe/config/ConfigObject.java
@@ -13,11 +13,9 @@ import java.util.Set;
  * a type that the value can't be converted to. ConfigException.Null is a
  * subclass of ConfigException.WrongType thrown if the value is null. The "path"
  * parameters for all the getters have periods between the key names, so the
- * path "a.b.c" looks for key c in object b in object a in the root object.
- *
- *
- * TODO If you need to look up a key with a period in its name, there isn't a
- * way to do it right now.
+ * path "a.b.c" looks for key c in object b in object a in the root object. (The
+ * syntax for paths is the same as in ${} substitution expressions in config
+ * files, sometimes double quotes are needed around special characters.)
  *
  * TODO add OrNull variants of all these getters? Or better to avoid convenience
  * API for that?
diff --git a/src/main/java/com/typesafe/config/impl/AbstractConfigObject.java b/src/main/java/com/typesafe/config/impl/AbstractConfigObject.java
index 67db777b..391fb3bb 100644
--- a/src/main/java/com/typesafe/config/impl/AbstractConfigObject.java
+++ b/src/main/java/com/typesafe/config/impl/AbstractConfigObject.java
@@ -112,37 +112,53 @@ abstract class AbstractConfigObject extends AbstractConfigValue implements
     }
 
     static private AbstractConfigValue resolve(AbstractConfigObject self,
-            String path,
+            String pathExpression,
             ConfigValueType expected, ConfigTransformer transformer,
             String originalPath) {
-        String key = ConfigUtil.firstElement(path);
-        String next = ConfigUtil.otherElements(path);
+        Path path = Path.newPath(pathExpression);
+        return resolve(self, path, expected, transformer, originalPath);
+    }
+
+    static private AbstractConfigValue resolveKey(AbstractConfigObject self,
+            String key, ConfigValueType expected,
+            ConfigTransformer transformer, String originalPath) {
+        AbstractConfigValue v = self.peek(key);
+        if (v == null)
+            throw new ConfigException.Missing(originalPath);
+
+        if (expected != null && transformer != null)
+            v = transformer.transform(v, expected);
+
+        if (v.valueType() == ConfigValueType.NULL)
+            throw new ConfigException.Null(v.origin(), originalPath,
+                    expected != null ? expected.name() : null);
+        else if (expected != null && v.valueType() != expected)
+            throw new ConfigException.WrongType(v.origin(), originalPath,
+                    expected.name(), v.valueType().name());
+        else
+            return v;
+    }
+
+    static private AbstractConfigValue resolve(AbstractConfigObject self,
+            Path path, ConfigValueType expected, ConfigTransformer transformer,
+            String originalPath) {
+        String key = path.first();
+        Path next = path.remainder();
         if (next == null) {
-            AbstractConfigValue v = self.peek(key);
-            if (v == null)
-                throw new ConfigException.Missing(originalPath);
-
-            if (expected != null && transformer != null)
-                v = transformer.transform(v, expected);
-
-            if (v.valueType() == ConfigValueType.NULL)
-                throw new ConfigException.Null(v.origin(), originalPath,
-                        expected != null ? expected.name() : null);
-            else if (expected != null && v.valueType() != expected)
-                throw new ConfigException.WrongType(v.origin(), originalPath,
-                        expected.name(), v.valueType().name());
-            else
-                return v;
+            return resolveKey(self, key, expected, transformer, originalPath);
         } else {
-            AbstractConfigObject o = self.getObject(key);
+            AbstractConfigObject o = (AbstractConfigObject) resolveKey(self,
+                    key, ConfigValueType.OBJECT, transformer, originalPath);
             assert (o != null); // missing was supposed to throw
             return resolve(o, next, expected, transformer, originalPath);
         }
     }
 
-    AbstractConfigValue resolve(String path, ConfigValueType expected,
+    AbstractConfigValue resolve(String pathExpression,
+            ConfigValueType expected,
             String originalPath) {
-        return resolve(this, path, expected, transformer, originalPath);
+        return resolve(this, pathExpression, expected, transformer,
+                originalPath);
     }
 
     /**
diff --git a/src/main/java/com/typesafe/config/impl/ConfigUtil.java b/src/main/java/com/typesafe/config/impl/ConfigUtil.java
index 19673519..39318fd6 100644
--- a/src/main/java/com/typesafe/config/impl/ConfigUtil.java
+++ b/src/main/java/com/typesafe/config/impl/ConfigUtil.java
@@ -1,54 +1,7 @@
 package com.typesafe.config.impl;
 
-import com.typesafe.config.ConfigException;
 
 final class ConfigUtil {
-    static void verifyPath(String path) {
-        if (path.startsWith("."))
-            throw new ConfigException.BadPath(path, "Path starts with '.'");
-        if (path.endsWith("."))
-            throw new ConfigException.BadPath(path, "Path ends with '.'");
-        if (path.contains(".."))
-            throw new ConfigException.BadPath(path,
-                    "Path contains '..' (empty element)");
-    }
-
-    static String firstElement(String path) {
-        verifyPath(path);
-        int i = path.indexOf('.');
-        if (i < 0)
-            return path;
-        else
-            return path.substring(0, i);
-    }
-
-    static String otherElements(String path) {
-        verifyPath(path);
-        int i = path.indexOf('.');
-        if (i < 0)
-            return null;
-        else
-            return path.substring(i + 1);
-    }
-
-    static String lastElement(String path) {
-        verifyPath(path);
-        int i = path.lastIndexOf('.');
-        if (i < 0)
-            return path;
-        else
-            return path.substring(i + 1);
-    }
-
-    static String exceptLastElement(String path) {
-        verifyPath(path);
-        int i = path.lastIndexOf('.');
-        if (i < 0)
-            return null;
-        else
-            return path.substring(0, i);
-    }
-
     static boolean equalsHandlingNull(Object a, Object b) {
         if (a == null && b != null)
             return false;
diff --git a/src/main/java/com/typesafe/config/impl/Loader.java b/src/main/java/com/typesafe/config/impl/Loader.java
index 3168a85b..a3000c48 100644
--- a/src/main/java/com/typesafe/config/impl/Loader.java
+++ b/src/main/java/com/typesafe/config/impl/Loader.java
@@ -79,6 +79,34 @@ final class Loader {
         }
     }
 
+    static void verifyPath(String path) {
+        if (path.startsWith("."))
+            throw new ConfigException.BadPath(path, "Path starts with '.'");
+        if (path.endsWith("."))
+            throw new ConfigException.BadPath(path, "Path ends with '.'");
+        if (path.contains(".."))
+            throw new ConfigException.BadPath(path,
+                    "Path contains '..' (empty element)");
+    }
+
+    static String lastElement(String path) {
+        verifyPath(path);
+        int i = path.lastIndexOf('.');
+        if (i < 0)
+            return path;
+        else
+            return path.substring(i + 1);
+    }
+
+    static String exceptLastElement(String path) {
+        verifyPath(path);
+        int i = path.lastIndexOf('.');
+        if (i < 0)
+            return null;
+        else
+            return path.substring(0, i);
+    }
+
     static AbstractConfigObject fromProperties(String originPrefix,
             Properties props) {
         Map<String, Map<String, AbstractConfigValue>> scopes = new HashMap<String, Map<String, AbstractConfigValue>>();
@@ -88,8 +116,8 @@ final class Loader {
             if (o instanceof String) {
                 try {
                     String path = (String) o;
-                    String last = ConfigUtil.lastElement(path);
-                    String exceptLast = ConfigUtil.exceptLastElement(path);
+                    String last = lastElement(path);
+                    String exceptLast = exceptLastElement(path);
                     if (exceptLast == null)
                         exceptLast = "";
                     Map<String, AbstractConfigValue> scope = scopes
@@ -116,7 +144,7 @@ final class Loader {
 
         // put everything in its parent, ensuring all parents exist
         for (String path : childPaths) {
-            String parentPath = ConfigUtil.exceptLastElement(path);
+            String parentPath = exceptLastElement(path);
             if (parentPath == null)
                 parentPath = "";
 
@@ -132,7 +160,7 @@ final class Loader {
             AbstractConfigObject o = new SimpleConfigObject(
                     new SimpleConfigOrigin(originPrefix + " " + path), null,
                     scopes.get(path));
-            String basename = ConfigUtil.lastElement(path);
+            String basename = lastElement(path);
             parent.put(basename, o);
         }
 
diff --git a/src/main/java/com/typesafe/config/impl/PathBuilder.java b/src/main/java/com/typesafe/config/impl/PathBuilder.java
index 5dd8a4fe..0f6a3d53 100644
--- a/src/main/java/com/typesafe/config/impl/PathBuilder.java
+++ b/src/main/java/com/typesafe/config/impl/PathBuilder.java
@@ -19,24 +19,6 @@ final class PathBuilder {
                     "Adding to PathBuilder after getting result");
     }
 
-    void appendPath(String path) {
-        checkCanAppend();
-        ConfigUtil.verifyPath(path);
-
-        String next = ConfigUtil.firstElement(path);
-        String remainder = ConfigUtil.otherElements(path);
-
-        while (next != null) {
-            keys.push(next);
-            if (remainder != null) {
-                next = ConfigUtil.firstElement(remainder);
-                remainder = ConfigUtil.otherElements(remainder);
-            } else {
-                next = null;
-            }
-        }
-    }
-
     void appendKey(String key) {
         checkCanAppend();
 
diff --git a/src/test/scala/com/typesafe/config/impl/ConfParserTest.scala b/src/test/scala/com/typesafe/config/impl/ConfParserTest.scala
index c63afa45..4245cc1d 100644
--- a/src/test/scala/com/typesafe/config/impl/ConfParserTest.scala
+++ b/src/test/scala/com/typesafe/config/impl/ConfParserTest.scala
@@ -63,6 +63,7 @@ class ConfParserTest extends TestUtils {
                         }
                 }
         }
+
         // also parse with the standalone path parser and be sure the
         // outcome is the same
         val shouldBeSame = Parser.parsePath(s)
@@ -93,6 +94,7 @@ class ConfParserTest extends TestUtils {
         assertEquals(path(""), parsePath("\"\"\"\""))
         assertEquals(path("a", ""), parsePath("a.\"\"\"\""))
         assertEquals(path("", "b"), parsePath("\"\"\"\".b"))
+        assertEquals(path("", "", ""), parsePath(""" "".""."" """))
 
         for (invalid <- Seq("a.", ".b", "a..b", "a${b}c", "\"\".", ".\"\"")) {
             try {
diff --git a/src/test/scala/com/typesafe/config/impl/ConfigTest.scala b/src/test/scala/com/typesafe/config/impl/ConfigTest.scala
index bd0b2070..88b19b23 100644
--- a/src/test/scala/com/typesafe/config/impl/ConfigTest.scala
+++ b/src/test/scala/com/typesafe/config/impl/ConfigTest.scala
@@ -370,7 +370,7 @@ class ConfigTest extends TestUtils {
     }
 
     @Test
-    def test02WeirdPaths() {
+    def test02SubstitutionsWithWeirdPaths() {
         val conf = Config.load("test02")
 
         assertEquals(42, conf.getInt("42_a"))
@@ -380,4 +380,16 @@ class ConfigTest extends TestUtils {
         assertEquals(57, conf.getInt("57_b"))
         assertEquals(103, conf.getInt("103_a"))
     }
+
+    @Test
+    def test02UseWeirdPathsWithConfigObject() {
+        val conf = Config.load("test02")
+
+        // we're checking that the getters in ConfigObject support
+        // these weird path expressions
+        assertEquals(42, conf.getInt(""" "".""."" """))
+        assertEquals(57, conf.getInt("a.b.c"))
+        assertEquals(57, conf.getInt(""" "a"."b"."c" """))
+        assertEquals(103, conf.getInt(""" "a.b.c" """))
+    }
 }