diff --git a/eraser-base/src/main/jastadd/Navigation.jrag b/eraser-base/src/main/jastadd/Navigation.jrag
index d12dc50b01de4ffec0b76dbf28a9f25d937896dd..13f9e2e9a3183877fff418f9701283a976e004c3 100644
--- a/eraser-base/src/main/jastadd/Navigation.jrag
+++ b/eraser-base/src/main/jastadd/Navigation.jrag
@@ -11,34 +11,48 @@ aspect Navigation {
     return result;
   }
 
+  //--- enclosingGroup ---
+  inh Group Group.enclosingGroup();
+  inh Group Item.enclosingGroup();
   eq Group.getItem().enclosingGroup() = this;
   eq Group.getGroup().enclosingGroup() = this;
   eq SmartHomeEntityModel.getGroup().enclosingGroup() = null;
+  eq SmartHomeEntityModel.getActivityItem().enclosingGroup() = null;
 
-  inh ItemPerformance Item.relevantItemPerformance();
-  inh ItemPerformance Group.relevantItemPerformance();
-  eq Group.getItem(int index).relevantItemPerformance() {
-    Item item = getItem(index);
-    // first, use value defined on item itself, if any
-    if (item.hasItemPerformance()) {
-      return item.getItemPerformance();
-    }
-    // then on this group, if defined
+  //--- relevantItemPerformance ---
+  syn ItemPerformance Group.relevantItemPerformance() {
+    // first, use value defined on group itself, if any
     if (this.hasItemPerformance()) {
       return this.getItemPerformance();
     }
+
     // recursively use enclosing group and use value from there, if any
     Group parent = enclosingGroup();
     if (parent != null) {
       return parent.relevantItemPerformance();
     }
+
     // if top-level group without ItemPerformance
     return null;
+
   }
+  syn ItemPerformance Item.relevantItemPerformance() {
+    // first, use value defined on item itself, if any
+    if (this.hasItemPerformance()) {
+      return this.getItemPerformance();
+    }
 
-  inh Group Group.enclosingGroup();
-  inh Group Item.enclosingGroup();
+    // use enclosing group and use value from there, if any
+    Group parent = enclosingGroup();
+    if (parent != null) {
+      return parent.relevantItemPerformance();
+    }
+
+    // if top-level item without ItemPerformance
+    return null;
+  }
 
+  //--- addItems ---
   private void SmartHomeEntityModel.addItems(java.util.List<Item> result, JastAddList<Group> groups) {
     groups.forEach(group -> group.getItemList().forEach(item -> result.add(item)));
   }
@@ -84,4 +98,5 @@ aspect Navigation {
   eq Root.getRule().getRoot() = this;
   eq Root.getUser().getRoot() = this;
   eq Root.getLocation().getRoot() = this;
+  eq Root.getItemPerformance().getRoot() = this;
 }
diff --git a/eraser-base/src/main/jastadd/Resolving.jrag b/eraser-base/src/main/jastadd/Resolving.jrag
index e1d793c1587afcd16b232197a2e87b21c9d6f08b..5c8df0bd0176e860fefcb5d278d037d7848fab9c 100644
--- a/eraser-base/src/main/jastadd/Resolving.jrag
+++ b/eraser-base/src/main/jastadd/Resolving.jrag
@@ -98,9 +98,22 @@ aspect Resolving {
     return java.util.Optional.empty();
   }
 
+  syn java.util.Optional<ItemPerformance> Root.resolveItemPerformance(String performanceId) {
+    for (ItemPerformance performance : getItemPerformanceList()) {
+      if (performance.getLabel().equals(performanceId)) {
+        return java.util.Optional.of(performance);
+      }
+    }
+    return java.util.Optional.empty();
+  }
+
   // implementing resolving for relations
   refine RefResolverStubs eq StateSyncGroup.resolveTargetItemByToken(String id, int position) {
     return getRoot().getSmartHomeEntityModel().resolveItem(id).orElseThrow(() -> new RuntimeException("Item '" + id + "' not found!"));
   }
 
+  refine RefResolverStubs eq ASTNode.globallyResolveItemPerformanceByToken(String id) {
+    return getRoot().resolveItemPerformance(id).orElseThrow(() -> new RuntimeException("ItemPerformance '" + id + "' not found!"));
+  }
+
 }