Fix merging of parameters

The merging logic was wrong, inverting the behaviour of parameter
merging, somewhat anyway.

This is now fixed. Entities are collected in a list, and then the list
is reduced through merging the second element into the first. The entity
of the current level is only merged once, at the very end.

Signed-off-by: martin f. krafft <madduck@madduck.net>
diff --git a/datatypes/entity.py b/datatypes/entity.py
index 02b5edf..363df61 100644
--- a/datatypes/entity.py
+++ b/datatypes/entity.py
@@ -25,8 +25,8 @@
     name = property(lambda self: self._name)
 
     def merge(self, other):
-        self.applications.merge(other.applications)
         self.classes.merge(other.classes)
+        self.applications.merge(other.applications)
         self.parameters.merge(other.parameters)
         self._name = other.name
 
diff --git a/storage/yaml_fs/__init__.py b/storage/yaml_fs/__init__.py
index 9843333..7ea4ae8 100644
--- a/storage/yaml_fs/__init__.py
+++ b/storage/yaml_fs/__init__.py
@@ -25,13 +25,31 @@
         try:
             entity = YamlFile(path).entity
             seen[name] = True
+
+            merge_base = None
             for klass in entity.classes:
                 if klass not in seen:
                     ret = self._read_nodeinfo(klass, self.classes_uri, seen,
                                               name if nodename is None else nodename)[0]
-                    ret.merge(entity)
-                    entity = ret
-            return entity, path
+                    if merge_base is None:
+                        # first iteration, initialise the merge base
+                        merge_base = ret
+                    else:
+                        # on every iteration, we merge the result of the
+                        # recursive descend into what we have so far…
+                        merge_base.merge(ret)
+
+            if merge_base is None:
+                # there are no parent classes, at least none we haven't
+                # already seen, so we can just return the entity
+                return entity, path
+
+            # … and finally, we merge what we have at this level into the
+            # result of the iteration, so that elements at the current level
+            # overwrite stuff defined by parents
+            merge_base.merge(entity)
+            return merge_base, path
+
         except IOError:
             if base_uri == self.classes_uri:
                 raise errors.ClassNotFound('yaml_fs', name, base_uri, nodename)
diff --git a/storage/yaml_fs/tests/test_yaml_fs.py b/storage/yaml_fs/tests/test_yaml_fs.py
index 7d99644..eae2f47 100644
--- a/storage/yaml_fs/tests/test_yaml_fs.py
+++ b/storage/yaml_fs/tests/test_yaml_fs.py
@@ -66,4 +66,9 @@
 
     def test_merge_empty_dict(self):
         node = self._storage.nodeinfo(HOSTS[0])
-        assert node['parameters'].get('apt') is not None
+        assert 'apt' in node['parameters']
+        assert node['parameters']['apt'] is not None
+
+    def test_merge_parameters(self):
+        node = self._storage.nodeinfo(HOSTS[1])
+        assert node['parameters']['apt']['mirror_base'] == 'uni-erlangen'