deal with ancestor references before deeper references
diff --git a/reclass/datatypes/parameters.py b/reclass/datatypes/parameters.py
index ece5b1c..91016d2 100644
--- a/reclass/datatypes/parameters.py
+++ b/reclass/datatypes/parameters.py
@@ -260,9 +260,10 @@
             # _interpolate_inner removes references from the refs hash after
             # processing them, so we cannot just iterate the dict
             path, value = self._unrendered.iteritems().next()
-            self._interpolate_inner(path, path.get_value(self._base), options)
+            self._interpolate_inner(path, options)
 
-    def _interpolate_inner(self, path, value, options):
+    def _interpolate_inner(self, path, options):
+        value = path.get_value(self._base)
         if not isinstance(value, (Value, ValueList)):
             # references to lists and dicts are only deepcopied when merged
             # together so it's possible a value with references in a referenced
@@ -282,8 +283,14 @@
                     # faced with a cyclical reference.
                     raise InfiniteRecursionError(path, ref)
                 else:
-                    value_inner = path_from_ref.get_value(self._base)
-                    self._interpolate_inner(path_from_ref, value_inner, options)
+                    self._interpolate_inner(path_from_ref, options)
+            else:
+                # ensure ancestor keys are already dereferenced
+                ancestor = DictPath(self.delimiter)
+                for k in path_from_ref.key_parts():
+                    ancestor = ancestor.new_subpath(k)
+                    if ancestor in self._unrendered:
+                        self._interpolate_inner(ancestor, options)
 
         if value.allRefs():
             # all references have been deferenced so render value
@@ -307,6 +314,6 @@
             old = len(value.get_references())
             value.assembleRefs(self._base)
             if old != len(value.get_references()):
-                self._interpolate_inner(path, value, options)
+                self._interpolate_inner(path, options)
             else:
                 raise InterpolationError('Bad reference count, path:' + repr(path))
diff --git a/reclass/datatypes/tests/test_parameters.py b/reclass/datatypes/tests/test_parameters.py
index c76b721..c1ef640 100644
--- a/reclass/datatypes/tests/test_parameters.py
+++ b/reclass/datatypes/tests/test_parameters.py
@@ -340,6 +340,12 @@
         p1.interpolate()
         self.assertEqual(p1.as_dict(), r)
 
+    def test_deep_refs_in_referenced_dicts(self):
+        p = Parameters({'A': '${C:a}', 'B': {'a': 1, 'b': 2}, 'C': '${B}'})
+        r = {'A': 1, 'B': {'a': 1, 'b': 2}, 'C': {'a': 1, 'b': 2}}
+        p.interpolate()
+        self.assertEqual(p.as_dict(), r)
+
     def test_interpolate_escaping(self):
         v = 'bar'.join(PARAMETER_INTERPOLATION_SENTINELS)
         d = {'foo': ESCAPE_CHARACTER + 'bar'.join(PARAMETER_INTERPOLATION_SENTINELS),
diff --git a/reclass/utils/dictpath.py b/reclass/utils/dictpath.py
index db95e66..7395679 100644
--- a/reclass/utils/dictpath.py
+++ b/reclass/utils/dictpath.py
@@ -112,6 +112,15 @@
     def _escape_string(self, string):
         return string.replace(self._delim, '\\' + self._delim)
 
+    def has_ancestors(self):
+        return len(self._parts) > 1
+
+    def key_parts(self):
+        if self.has_ancestors():
+            return self._parts[::len(self._parts)-1]
+        else:
+            return []
+
     def new_subpath(self, key):
         try:
             return DictPath(self._delim, self._parts + [self._escape_string(key)])