diff --git a/src/datastore.py b/src/datastore.py
index c6f200bb081ac6ad5ab7661d5cc4419098ca0c1d..348f28549e716a30605ff2be5894fd5b03b4dc95 100644
--- a/src/datastore.py
+++ b/src/datastore.py
@@ -2,7 +2,8 @@ __author__ = 'Lukas Leufen'
 __date__ = '2019-11-22'
 
 
-from typing import Any, List
+from typing import Any, List, Tuple
+
 from abc import ABC
 
 
@@ -109,7 +110,7 @@ class DataStoreByVariable(AbstractDataStore):
             self._store[name] = {}
         self._store[name][scope] = obj
 
-    def get(self, name: str, scope: str, depth: int = None) -> Any:
+    def get(self, name: str, scope: str) -> Any:
         """
         Retrieve an object with `name` from `scope`. If no object can be found in the exact scope, take an iterative
         look on the levels above. Raises a NameNotFoundInDataStore error, if no object with given name can be found in
@@ -117,23 +118,24 @@ class DataStoreByVariable(AbstractDataStore):
         given scope and its levels above (could be either included in another scope or a more detailed sub-scope).
         :param name: Name to look for
         :param scope: scope to search the name for
-        :param depth: counter to check, if all roots of the scope have been visited to trigger an error.
         :return: the stored object
         """
-        if depth is None:
-            depth = scope.count(".")
-        if depth >= 0:
+        return self._stride_through_scopes(name, scope)[2]
+
+    def _stride_through_scopes(self, name, scope, depth=0):
+        if depth <= scope.count("."):
+            local_scope = scope.rsplit(".", maxsplit=depth)[0]
             try:
-                return self._store[name][scope]
+                return name, local_scope, self._store[name][local_scope]
             except KeyError:
-                return self.get(name, scope.rsplit(".", maxsplit=depth)[0], depth-1)
+                return self._stride_through_scopes(name, scope, depth + 1)
         else:
-            try:
-                occurrences = self.search_name(name)
-                raise NameNotFoundInScope(f"Couldn't find {name} in scope {scope}. {name} is only defined in "
-                                          f"{occurrences}")
-            except KeyError:
+            occurrences = self.search_name(name)
+            if len(occurrences) == 0:
                 raise NameNotFoundInDataStore(f"Couldn't find {name} in data store")
+            else:
+                raise NameNotFoundInScope(f"Couldn't find {name} in scope {scope} . {name} is only defined in "
+                                          f"{occurrences}")
 
     def search_name(self, name: str) -> List[str]:
         """
@@ -141,23 +143,47 @@ class DataStoreByVariable(AbstractDataStore):
         :param name: Name to look for
         :return: list with all scopes and sub-scopes containing an object stored as `name`
         """
-        return sorted(self._store[name])
+        return sorted(self._store[name] if name in self._store.keys() else [])
 
-    def search_scope(self, scope: str) -> List[str]:
+    def search_scope(self, scope: str, current_scope_only=True, return_all=False) -> List[str or Tuple]:
         """
-        Search for given `scope` and list all object names stored under this scope.
+        Search for given `scope` and list all object names stored under this scope. To look also for all superior scopes
+        set `current_scope_only=False`. To return the scope and the object's value too, set `return_all=True`.
         :param scope: scope to look for
-        :return: list with all object names
+        :param current_scope_only: look only for all names for given scope if true, else search for names from superior
+            scopes too.
+        :param return_all: return name, definition scope and value if True, else just the name
+        :return: list with all object names (if `return_all=False`) or list with tuple of object name, object scope and
+            object value ordered by name (if `return_all=True`)
         """
-        names = []
-        for (k, v) in self._store.items():
-            if scope in v.keys():
-                names.append(k)
-        if len(names) > 0:
-            return sorted(names)
+        if current_scope_only:
+            names = []
+            for (k, v) in self._store.items():
+                if scope in v.keys():
+                    names.append(k)
+            if len(names) > 0:
+                if return_all:
+                    return sorted([(name, scope, self._store[name][scope]) for name in names], key=lambda tup: tup[0])
+                else:
+                    return sorted(names)
+            else:
+                raise EmptyScope(f"Given scope {scope} is not part of the data store. Available scopes are: "
+                                 f"{self.list_all_scopes()}")
         else:
-            raise EmptyScope(f"Given scope {scope} is not part of the data store. Available scopes are: "
-                             f"{self.list_all_scopes()}")
+            results = []
+            for name in self.list_all_names():
+                try:
+                    res = self._stride_through_scopes(name, scope)
+                    if return_all:
+                        results.append(res)
+                    else:
+                        results.append(res[0])
+                except (NameNotFoundInDataStore, NameNotFoundInScope):
+                    pass
+            if return_all:
+                return sorted(results, key=lambda tup: tup[0])
+            else:
+                return sorted(results)
 
     def list_all_scopes(self) -> List[str]:
         """
@@ -171,6 +197,13 @@ class DataStoreByVariable(AbstractDataStore):
                     scopes.append(scope)
         return sorted(scopes)
 
+    def list_all_names(self) -> List[str]:
+        """
+        List all names available in the data store.
+        :return: all names
+        """
+        return sorted(self._store.keys())
+
 
 class DataStoreByScope(AbstractDataStore):
 
@@ -200,7 +233,7 @@ class DataStoreByScope(AbstractDataStore):
             self._store[scope] = {}
         self._store[scope][name] = obj
 
-    def get(self, name: str, scope: str, depth: int = None) -> Any:
+    def get(self, name: str, scope: str) -> Any:
         """
         Retrieve an object with `name` from `scope`. If no object can be found in the exact scope, take an iterative
         look on the levels above. Raises a NameNotFoundInDataStore error, if no object with given name can be found in
@@ -208,26 +241,25 @@ class DataStoreByScope(AbstractDataStore):
         given scope and its levels above (could be either included in another scope or a more detailed sub-scope).
         :param name: Name to look for
         :param scope: scope to search the name for
-        :param depth: counter to check, if all roots of the scope have been visited to trigger an error.
         :return: the stored object
         """
-        if depth is None:
-            depth = scope.count(".")
-        if depth >= 0:
+        return self._stride_through_scopes(name, scope)[2]
+
+    def _stride_through_scopes(self, name, scope, depth=0):
+        if depth <= scope.count("."):
+            local_scope = scope.rsplit(".", maxsplit=depth)[0]
             try:
-                return self._store[scope][name]
+                return name, local_scope, self._store[local_scope][name]
             except KeyError:
-                return self.get(name, scope.rsplit(".", maxsplit=1)[0], depth-1)
+                return self._stride_through_scopes(name, scope, depth + 1)
         else:
             occurrences = self.search_name(name)
             if len(occurrences) == 0:
                 raise NameNotFoundInDataStore(f"Couldn't find {name} in data store")
             else:
-                raise NameNotFoundInScope(f"Couldn't find {name} in scope {scope}. {name} is only defined in "
+                raise NameNotFoundInScope(f"Couldn't find {name} in scope {scope} . {name} is only defined in "
                                           f"{occurrences}")
 
-            
-
     def search_name(self, name: str) -> List[str]:
         """
         Search for all occurrences of given `name` in the entire data store.
@@ -240,17 +272,41 @@ class DataStoreByScope(AbstractDataStore):
                 keys.append(key)
         return sorted(keys)
 
-    def search_scope(self, scope: str, current_scope_only=True) -> List[str]:
+    def search_scope(self, scope: str, current_scope_only: bool = True, return_all: bool = False) -> List[str or Tuple]:
         """
-        Search for given `scope` and list all object names stored under this scope.
+        Search for given `scope` and list all object names stored under this scope. To look also for all superior scopes
+        set `current_scope_only=False`. To return the scope and the object's value too, set `return_all=True`.
         :param scope: scope to look for
-        :return: list with all object names
+        :param current_scope_only: look only for all names for given scope if true, else search for names from superior
+            scopes too.
+        :param return_all: return name, definition scope and value if True, else just the name
+        :return: list with all object names (if `return_all=False`) or list with tuple of object name, object scope and
+            object value ordered by name (if `return_all=True`)
         """
-        try:
-            return sorted(self._store[scope].keys())
-        except KeyError:
-            raise EmptyScope(f"Given scope {scope} is not part of the data store. Available scopes are: "
-                             f"{self.list_all_scopes()}")
+        if current_scope_only:
+            try:
+                if return_all:
+                    return [(name, scope, self._store[scope][name]) for name in sorted(self._store[scope].keys())]
+                else:
+                    return sorted(self._store[scope].keys())
+            except KeyError:
+                raise EmptyScope(f"Given scope {scope} is not part of the data store. Available scopes are: "
+                                 f"{self.list_all_scopes()}")
+        else:
+            results = []
+            for name in self.list_all_names():
+                try:
+                    res = self._stride_through_scopes(name, scope)
+                    if return_all:
+                        results.append(res)
+                    else:
+                        results.append(res[0])
+                except (NameNotFoundInDataStore, NameNotFoundInScope):
+                    pass
+            if return_all:
+                return sorted(results, key=lambda tup: tup[0])
+            else:
+                return sorted(results)
 
     def list_all_scopes(self) -> List[str]:
         """
@@ -259,3 +315,17 @@ class DataStoreByScope(AbstractDataStore):
         """
         return sorted(self._store.keys())
 
+    def list_all_names(self) -> List[str]:
+        """
+        List all names available in the data store.
+        :return: all names
+        """
+        names = []
+        scopes = self.list_all_scopes()
+        for scope in scopes:
+            for name in self._store[scope].keys():
+                if name not in names:
+                    names.append(name)
+        return sorted(names)
+
+
diff --git a/test/test_datastore.py b/test/test_datastore.py
index 1434508b6d033aa0e915ace6bcc1eafb0febe638..5ba76bf8fc9c21553723cba3b2125be2d758e23b 100644
--- a/test/test_datastore.py
+++ b/test/test_datastore.py
@@ -58,12 +58,13 @@ class TestDataStoreByVariable:
     def test_raise_not_in_scope(self, ds):
         ds.put("number", 11, "general.sub")
         with pytest.raises(NameNotFoundInScope) as e:
-            ds.get("number", "general")
-        assert "Couldn't find number in scope general. number is only defined in ['general.sub']" in e.value.args[0]
+            ds.get("number", "general.sub2")
+        assert "Couldn't find number in scope general.sub2 . number is only defined in ['general.sub']" in e.value.args[0]
 
     def test_list_all_scopes(self, ds):
         ds.put("number", 22, "general2")
         ds.put("number", 11, "general.sub")
+        ds.put("number2", 2, "general.sub")
         ds.put("number", 3, "general.sub3")
         ds.put("number", 1, "general")
         assert ds.list_all_scopes() == ['general', 'general.sub', 'general.sub3', 'general2']
@@ -83,6 +84,40 @@ class TestDataStoreByVariable:
         assert "Given scope general.sub2 is not part of the data store." in e.value.args[0]
         assert "Available scopes are: ['general.sub', 'general2']" in e.value.args[0]
 
+    def test_list_all_names(self, ds):
+        ds.put("number", 22, "general")
+        ds.put("number", 11, "general.sub")
+        ds.put("number1", 22, "general.sub")
+        ds.put("number2", 3, "general.sub.sub")
+        assert ds.list_all_names() == ["number", "number1", "number2"]
+
+    def test_search_scope_and_all_superiors(self, ds):
+        ds.put("number", 22, "general")
+        ds.put("number", 11, "general.sub")
+        ds.put("number1", 22, "general.sub")
+        ds.put("number2", 3, "general.sub.sub")
+        assert ds.search_scope("general.sub", current_scope_only=False) == ["number", "number1"]
+        assert ds.search_scope("general.sub.sub", current_scope_only=False) == ["number", "number1", "number2"]
+
+    def test_search_scope_return_all(self, ds):
+        ds.put("number", 22, "general")
+        ds.put("number", 11, "general.sub")
+        ds.put("number1", 22, "general.sub")
+        ds.put("number2", 3, "general.sub.sub")
+        assert ds.search_scope("general.sub", return_all=True) == [("number", "general.sub", 11),
+                                                                   ("number1", "general.sub", 22)]
+
+    def test_search_scope_and_all_superiors_return_all(self, ds):
+        ds.put("number", 22, "general")
+        ds.put("number", 11, "general.sub")
+        ds.put("number1", 22, "general.sub")
+        ds.put("number2", 3, "general.sub.sub")
+        ds.put("number", "ABC", "general.sub.sub")
+        assert ds.search_scope("general.sub", current_scope_only=False, return_all=True) == \
+            [("number", "general.sub", 11), ("number1", "general.sub", 22)]
+        assert ds.search_scope("general.sub.sub", current_scope_only=False, return_all=True) == \
+            [("number", "general.sub.sub", "ABC"), ("number1", "general.sub", 22), ("number2", "general.sub.sub", 3)]
+
 
 class TestDataStoreByScope:
 
@@ -125,12 +160,13 @@ class TestDataStoreByScope:
     def test_raise_not_in_scope(self, ds):
         ds.put("number", 11, "general.sub")
         with pytest.raises(NameNotFoundInScope) as e:
-            ds.get("number", "general")
-        assert "Couldn't find number in scope general. number is only defined in ['general.sub']" in e.value.args[0]
+            ds.get("number", "general.sub2")
+        assert "Couldn't find number in scope general.sub2 . number is only defined in ['general.sub']" in e.value.args[0]
 
     def test_list_all_scopes(self, ds):
         ds.put("number", 22, "general2")
         ds.put("number", 11, "general.sub")
+        ds.put("number2", 2, "general.sub")
         ds.put("number", 3, "general.sub3")
         ds.put("number", 1, "general")
         assert ds.list_all_scopes() == ['general', 'general.sub', 'general.sub3', 'general2']
@@ -150,6 +186,13 @@ class TestDataStoreByScope:
         assert "Given scope general.sub2 is not part of the data store." in e.value.args[0]
         assert "Available scopes are: ['general.sub', 'general2']" in e.value.args[0]
 
+    def test_list_all_names(self, ds):
+        ds.put("number", 22, "general")
+        ds.put("number", 11, "general.sub")
+        ds.put("number1", 22, "general.sub")
+        ds.put("number2", 3, "general.sub.sub")
+        assert ds.list_all_names() == ["number", "number1", "number2"]
+
     def test_search_scope_and_all_superiors(self, ds):
         ds.put("number", 22, "general")
         ds.put("number", 11, "general.sub")
@@ -158,3 +201,22 @@ class TestDataStoreByScope:
         assert ds.search_scope("general.sub", current_scope_only=False) == ["number", "number1"]
         assert ds.search_scope("general.sub.sub", current_scope_only=False) == ["number", "number1", "number2"]
 
+    def test_search_scope_return_all(self, ds):
+        ds.put("number", 22, "general")
+        ds.put("number", 11, "general.sub")
+        ds.put("number1", 22, "general.sub")
+        ds.put("number2", 3, "general.sub.sub")
+        assert ds.search_scope("general.sub", return_all=True) == [("number", "general.sub", 11),
+                                                                   ("number1", "general.sub", 22)]
+
+    def test_search_scope_and_all_superiors_return_all(self, ds):
+        ds.put("number", 22, "general")
+        ds.put("number", 11, "general.sub")
+        ds.put("number1", 22, "general.sub")
+        ds.put("number2", 3, "general.sub.sub")
+        ds.put("number", "ABC", "general.sub.sub")
+        assert ds.search_scope("general.sub", current_scope_only=False, return_all=True) == \
+            [("number", "general.sub", 11), ("number1", "general.sub", 22)]
+        assert ds.search_scope("general.sub.sub", current_scope_only=False, return_all=True) == \
+            [("number", "general.sub.sub", "ABC"), ("number1", "general.sub", 22), ("number2", "general.sub.sub", 3)]
+