Fix parameter interpolation across merged lists

This was easier than thought. The problem:

   If two lists are merged (extended), and those lists use RefValues,
   then expansion (interpolation) won't work. The reason is that the
   DictPath includes the list indices, e.g. apt_repos:0:uri and those
   indices start at 0 for every list. Now, when two lists are merged,
   the reference to the base RefValue (in Parameters._occurrences) is
   overwritten by the RefValue of the mergee, causing it to not get
   expanded later.

Instead of just updating self._occurrences, we can populate it as we
update scalars, and on extending lists, we can add an offset to the
index in the path of the mergee.

Still: DictPath should go. One day…

Closes: #13
Signed-off-by: martin f. krafft <madduck@madduck.net>
diff --git a/doc/source/changelog.rst b/doc/source/changelog.rst
index 1bd522a..a5b95e4 100644
--- a/doc/source/changelog.rst
+++ b/doc/source/changelog.rst
@@ -5,6 +5,8 @@
 ========= ========== ========================================================
 Version   Date       Changes
 ========= ========== ========================================================
+                     * Fix parameter interpolation across merged lists
+                       (closes: #13).
                      * Caching of classes for performance reasons, especially
                        during the inventory runs
                      * yaml_fs: nodes may be defined in subdirectories
diff --git a/reclass/datatypes/parameters.py b/reclass/datatypes/parameters.py
index 078a247..7f0f33a 100644
--- a/reclass/datatypes/parameters.py
+++ b/reclass/datatypes/parameters.py
@@ -70,30 +70,46 @@
         return self._base.copy()
 
     def _update_scalar(self, cur, new, path):
-        if self.delimiter is None or not isinstance(new, types.StringTypes):
+        if self.delimiter is None or not isinstance(new, (types.StringTypes,
+                                                          RefValue)):
+            # either there is no delimiter defined (and hence no references
+            # are being used), or the new value is not a string (and hence
+            # cannot be turned into a RefValue), and not a RefValue. We can
+            # shortcut and just return the new scalar
             return new
 
+        elif isinstance(new, RefValue):
+            # the new value is (already) a RefValue, so we need not touch it
+            # at all
+            ret = new
+
         else:
+            # the new value is a string, let's see if it contains references,
+            # by way of wrapping it in a RefValue and querying the result
             ret = RefValue(new, self.delimiter)
             if not ret.has_references():
                 # do not replace with RefValue instance if there are no
-                # references
+                # references, i.e. discard the RefValue in ret, just return
+                # the new value
                 return new
 
-            # finally, keep a reference to the RefValue instance we just
-            # created, in a dict indexed by the dictionary path, instead of
-            # just a list. The keys are required to resolve dependencies
-            # during interpolation
-            self._occurrences[path] = ret
-            return ret
+        # So we now have a RefValue. Let's, keep a reference to the instance
+        # we just created, in a dict indexed by the dictionary path, instead
+        # of just a list. The keys are required to resolve dependencies during
+        # interpolation
+        self._occurrences[path] = ret
+        return ret
 
     def _extend_list(self, cur, new, path):
         if isinstance(cur, list):
             ret = cur
+            offset = len(cur)
         else:
             ret = [cur]
+            offset = 1
+
         for i in xrange(len(new)):
-            ret.append(self._merge_recurse(None, new[i], path.new_subpath(i)))
+            ret.append(self._merge_recurse(None, new[i], path.new_subpath(offset + i)))
         return ret
 
     def _merge_dict(self, cur, new, path):
@@ -140,7 +156,6 @@
         elif isinstance(other, self.__class__):
             self._base = self._merge_recurse(self._base, other._base,
                                              None)
-            self._occurrences.update(other._occurrences)
 
         else:
             raise TypeError('Cannot merge %s objects into %s' % (type(other),