use better algorithm for individual export evaluation
diff --git a/reclass/datatypes/exports.py b/reclass/datatypes/exports.py
index 91bc149..375ea0b 100644
--- a/reclass/datatypes/exports.py
+++ b/reclass/datatypes/exports.py
@@ -10,6 +10,7 @@
 from reclass.errors import ResolveError
 from reclass.values.value import Value
 from reclass.values.valuelist import ValueList
+from reclass.utils.dictpath import DictPath
 
 class Exports(Parameters):
 
@@ -43,32 +44,40 @@
                 del self._unrendered[path]
 
     def interpolate_single_from_external(self, external, query):
-        paths = {}
         for r in query.get_inv_references():
-            paths[r] = True
+            self._interpolate_single_path_from_external(r, external, query)
 
-        rendered = {}
-        while len(paths) > 0:
-            path, v = paths.iteritems().next()
-            rendpath = path.deepest_match_in(self._base)
-            if rendpath in rendered:
-                del paths[path]
-                continue
-            if rendpath.exists_in(self._base) and rendpath in self._unrendered:
-                value = rendpath.get_value(self._base)
+    def _interpolate_single_path_from_external(self, mainpath, external, query):
+        required = self._get_required_paths(mainpath)
+        while len(required) > 0:
+            while len(required) > 0:
+                path, v = required.iteritems().next()
+                value = path.get_value(self._base)
                 if isinstance(value, (Value, ValueList)):
                     try:
-                        external._interpolate_references(rendpath, value, None)
-                        new = self._interpolate_render_from_external(external._base, rendpath, value)
-                        rendpath.set_value(self._base, new)
+                        external._interpolate_references(path, value, None)
+                        new = self._interpolate_render_from_external(external._base, path, value)
+                        path.set_value(self._base, new)
                     except ResolveError as e:
                         if query.ignore_failed_render():
-                            rendpath.delete(self._base)
+                            path.delete(self._base)
                         else:
                             raise
-            rendered[rendpath] = True
-            paths.pop(rendpath, None)
-            self._unrendered.pop(rendpath, None)
+                del required[path]
+                del self._unrendered[path]
+            required = self._get_required_paths(mainpath)
+
+    def _get_required_paths(self, mainpath):
+        paths = {}
+        path = DictPath(self._settings.delimiter)
+        for i in mainpath.key_parts():
+            path.new_subpath(i)
+            if path in self._unrendered:
+                paths[path] = True
+        for i in self._unrendered:
+            if mainpath.is_ancestor_of(i) or mainpath == i:
+                paths[i] = True
+        return paths
 
     def _interpolate_render_from_external(self, context, path, value):
         try:
diff --git a/reclass/datatypes/tests/test_entity.py b/reclass/datatypes/tests/test_entity.py
index fde8067..1af9caa 100644
--- a/reclass/datatypes/tests/test_entity.py
+++ b/reclass/datatypes/tests/test_entity.py
@@ -187,6 +187,28 @@
         self.assertDictEqual(node3_parameters.as_dict(), res_params)
         self.assertDictEqual(inventory, res_inv)
 
+    def test_exports_multiple_nodes(self):
+        node1_exports = Exports({'a': '${a}'}, SETTINGS, '')
+        node1_parameters = Parameters({'name': 'node1', 'a': { 'test': '${b}' }, 'b': 1, 'exp': '$[ exports:a ]'}, SETTINGS, '')
+        node1_entity = Entity(SETTINGS, classes=None, applications=None, parameters=node1_parameters, exports=node1_exports)
+        node2_exports = Exports({'a': '${a}'}, SETTINGS, '')
+        node2_parameters = Parameters({'name': 'node2', 'a': { 'test': '${b}' }, 'b': 2 }, SETTINGS, '')
+        node2_entity = Entity(SETTINGS, classes=None, applications=None, parameters=node2_parameters, exports=node2_exports)
+        node1_entity.initialise_interpolation()
+        node2_entity.initialise_interpolation()
+        queries = node1_entity.parameters.get_inv_queries()
+        for p, q in queries:
+            node1_entity.interpolate_single_export(q)
+            node2_entity.interpolate_single_export(q)
+        res_inv = {'node1': {'a': {'test': 1}}, 'node2': {'a': {'test': 2}}}
+        res_params = {'a': {'test': 1}, 'b': 1, 'name': 'node1', 'exp': {'node1': {'test': 1}, 'node2': {'test': 2}}}
+        inventory = {}
+        inventory['node1'] = node1_entity.exports.as_dict()
+        inventory['node2'] = node2_entity.exports.as_dict()
+        node1_entity.interpolate(inventory)
+        self.assertDictEqual(node1_parameters.as_dict(), res_params)
+        self.assertDictEqual(inventory, res_inv)
+
     def test_exports_with_nested_references(self):
         inventory = {'node1': {'alpha': {'a': 1, 'b': 2}}, 'node2': {'alpha': {'a': 3, 'b': 4}}}
         node3_exports = Exports({'alpha': '${alpha}'}, SETTINGS, '')
diff --git a/reclass/utils/dictpath.py b/reclass/utils/dictpath.py
index eae57a1..28a738f 100644
--- a/reclass/utils/dictpath.py
+++ b/reclass/utils/dictpath.py
@@ -140,6 +140,14 @@
     def delete(self, base):
         del self._get_innermost_container(base)[self._get_key()]
 
+    def is_ancestor_of(self, other):
+        if len(other._parts) <= len(self._parts):
+            return False
+        for i in range(len(self._parts)):
+            if other._parts[i] != self._parts[i]:
+                return False
+        return True
+
     def exists_in(self, container):
         item = container
         for i in self._parts:
@@ -158,21 +166,21 @@
                     return False
         return True
 
-    def deepest_match_in(self, container):
-        match = DictPath(self._delim)
-        item = container
-        for i in self._parts:
-            if isinstance(item, (dict, list)):
-                if i in item:
-                    if isinstance(item, dict):
-                        item = item[i]
-                    elif isinstance(container, list):
-                        item = item[int(i)]
-                    match = match.new_subpath(i)
-                else:
-                    return match
-            else:
-                if item == self._parts[-1]:
-                    match = match.new_subpath(i)
-                return match
-        return match
+#    def deepest_match_in(self, container):
+#        match = DictPath(self._delim)
+#        item = container
+#        for i in self._parts:
+#            if isinstance(item, (dict, list)):
+#                if i in item:
+#                    if isinstance(item, dict):
+#                        item = item[i]
+#                    elif isinstance(container, list):
+#                        item = item[int(i)]
+#                    match = match.new_subpath(i)
+#                else:
+#                    return match
+#            else:
+#                if item == self._parts[-1]:
+#                    match = match.new_subpath(i)
+#                return match
+#        return match