Index: /branches/2839_HiveProjectManagement/HeuristicLab.Clients.Hive.Administrator/3.3/Views/ProjectPermissionsView.Designer.cs
===================================================================
--- /branches/2839_HiveProjectManagement/HeuristicLab.Clients.Hive.Administrator/3.3/Views/ProjectPermissionsView.Designer.cs	(revision 15921)
+++ /branches/2839_HiveProjectManagement/HeuristicLab.Clients.Hive.Administrator/3.3/Views/ProjectPermissionsView.Designer.cs	(revision 15922)
@@ -31,5 +31,5 @@
       this.splitContainer = new System.Windows.Forms.SplitContainer();
       this.permissionsGroupBox = new System.Windows.Forms.GroupBox();
-      this.treeView = new System.Windows.Forms.TreeView();
+      this.treeView = new Hive.Views.TreeView.NoDoubleClickTreeView();
       this.detailsGroupBox = new System.Windows.Forms.GroupBox();
       this.detailsViewHost = new HeuristicLab.MainForm.WindowsForms.ViewHost();
@@ -184,5 +184,5 @@
     private System.Windows.Forms.SplitContainer splitContainer;
     private System.Windows.Forms.GroupBox permissionsGroupBox;
-    private System.Windows.Forms.TreeView treeView;
+    private HeuristicLab.Clients.Hive.Views.TreeView.NoDoubleClickTreeView treeView;
     private System.Windows.Forms.GroupBox detailsGroupBox;
     private MainForm.WindowsForms.ViewHost detailsViewHost;
Index: /branches/2839_HiveProjectManagement/HeuristicLab.Clients.Hive.Administrator/3.3/Views/ProjectResourcesView.Designer.cs
===================================================================
--- /branches/2839_HiveProjectManagement/HeuristicLab.Clients.Hive.Administrator/3.3/Views/ProjectResourcesView.Designer.cs	(revision 15921)
+++ /branches/2839_HiveProjectManagement/HeuristicLab.Clients.Hive.Administrator/3.3/Views/ProjectResourcesView.Designer.cs	(revision 15922)
@@ -30,5 +30,5 @@
       this.splitContainer = new System.Windows.Forms.SplitContainer();
       this.resourcesGroupBox = new System.Windows.Forms.GroupBox();
-      this.treeView = new System.Windows.Forms.TreeView();
+      this.treeView = new Hive.Views.TreeView.NoDoubleClickTreeView();
       this.imageList = new System.Windows.Forms.ImageList(this.components);
       this.detailsGroupBox = new System.Windows.Forms.GroupBox();
@@ -185,5 +185,5 @@
     private System.Windows.Forms.GroupBox resourcesGroupBox;
     private System.Windows.Forms.GroupBox detailsGroupBox;
-    private System.Windows.Forms.TreeView treeView;
+    private HeuristicLab.Clients.Hive.Views.TreeView.NoDoubleClickTreeView treeView;
     private System.Windows.Forms.ImageList imageList;
     private MainForm.WindowsForms.ViewHost detailsViewHost;
Index: /branches/2839_HiveProjectManagement/HeuristicLab.Clients.Hive.Administrator/3.3/Views/ProjectResourcesView.cs
===================================================================
--- /branches/2839_HiveProjectManagement/HeuristicLab.Clients.Hive.Administrator/3.3/Views/ProjectResourcesView.cs	(revision 15921)
+++ /branches/2839_HiveProjectManagement/HeuristicLab.Clients.Hive.Administrator/3.3/Views/ProjectResourcesView.cs	(revision 15922)
@@ -1,5 +1,5 @@
 ﻿#region License Information
 /* HeuristicLab
- * Copyright (C) 2002-2017 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ * Copyright (C) 2002-2018 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
  *
  * This file is part of HeuristicLab.
@@ -51,9 +51,4 @@
     private readonly HashSet<Resource> newIncludedResources = new HashSet<Resource>();
 
-    private readonly Dictionary<Guid, HashSet<Project>> projectAncestors = new Dictionary<Guid, HashSet<Project>>();
-    private readonly Dictionary<Guid, HashSet<Project>> projectDescendants = new Dictionary<Guid, HashSet<Project>>();
-    private readonly Dictionary<Guid, HashSet<Resource>> resourceAncestors = new Dictionary<Guid, HashSet<Resource>>();
-    private readonly Dictionary<Guid, HashSet<Resource>> resourceDescendants = new Dictionary<Guid, HashSet<Resource>>();
-
     private readonly Color addedAssignmentColor = Color.FromArgb(255, 87, 191, 193); // #57bfc1
     private readonly Color removedAssignmentColor = Color.FromArgb(255, 236, 159, 72); // #ec9f48
@@ -83,11 +78,9 @@
         newAssignedResources.Clear();
         includedResources.Clear();
-        resourceAncestors.Clear();
         treeView.Nodes.Clear();
         detailsViewHost.Content = null;
       } else {
-        UpdateProjectGenealogy();
         UpdateAssignedResources();
-        UpdateResourceGenealogy();
+        UpdateIncludedResources();
         var top = BuildResourceTree(HiveAdminClient.Instance.Resources);
         detailsViewHost.Content = top;
@@ -111,7 +104,7 @@
 
     private void refreshButton_Click(object sender, EventArgs e) {
-      UpdateProjectGenealogy();
+      HiveAdminClient.Instance.Refresh();
       UpdateAssignedResources();
-      UpdateResourceGenealogy();
+      UpdateIncludedResources();
       var top = BuildResourceTree(HiveAdminClient.Instance.Resources);
       detailsViewHost.Content = top;
@@ -144,5 +137,5 @@
         e.Cancel = true;
       } else if (!HiveRoles.CheckAdminUserPermissions()) {
-          if (!projectAncestors[Content.Id].Any() || projectExclusiveResources.Contains(checkedResource)) {
+          if (!HiveAdminClient.Instance.GetAvailableProjectAncestors(Content.Id).Any() || projectExclusiveResources.Contains(checkedResource)) {
             e.Cancel = true;
           }
@@ -166,5 +159,6 @@
     private void UpdateResourceTree() {
       UpdateAssignedResources();
-      UpdateResourceGenealogy();
+      UpdateIncludedResources();
+
       var top = BuildResourceTree(HiveAdminClient.Instance.Resources);
       detailsViewHost.Content = top;
@@ -194,7 +188,6 @@
       // look up for assignments of ancestor projects
       var projectIds = new HashSet<Guid>();
-      if(projectAncestors.ContainsKey(projectId)) {
-        projectAncestors[projectId].ToList().ForEach(x => projectIds.Add(x.Id));
-      }
+      HiveClient.Instance.GetAvailableProjectAncestors(projectId).ToList().ForEach(x => projectIds.Add(x.Id));
+
       var ancestorProjectResources = resources.Where(x => 
         HiveAdminClient.Instance.ProjectResourceAssignments
@@ -206,8 +199,6 @@
       HashSet<Resource> availableResources = new HashSet<Resource>(ancestorProjectResources);
       foreach (var r in ancestorProjectResources) {
-        if(resourceDescendants.ContainsKey(r.Id)) {
-          foreach(var d in resourceDescendants[r.Id]) {
-            availableResources.Add(d);
-          }
+        foreach(var d in HiveAdminClient.Instance.GetAvailableResourceDescendants(r.Id)) {
+          availableResources.Add(d);
         }
       }
@@ -222,9 +213,7 @@
       if (projectExclusiveResources.Any()) {
         foreach (var r in projectExclusiveResources.ToArray()) {
-          if (resourceDescendants.ContainsKey(r.Id)) {
-            foreach (var d in resourceDescendants[r.Id]) {
-              projectExclusiveResources.Add(d);
-            }
-          }
+          foreach (var d in HiveAdminClient.Instance.GetAvailableResourceDescendants(r.Id)) {
+            projectExclusiveResources.Add(d);
+          }  
         }
       }
@@ -251,5 +240,5 @@
     private void UpdateNewAssignedResources() {
       for(int i = newAssignedResources.Count -1; i >= 0; i--) {
-        if(newAssignedResources.Intersect(resourceAncestors[newAssignedResources.ElementAt(i).Id]).Any()) {
+        if(newAssignedResources.Intersect(HiveAdminClient.Instance.GetAvailableResourceAncestors(newAssignedResources.ElementAt(i).Id)).Any()) {
           newAssignedResources.Remove(newAssignedResources.ElementAt(i));
         }
@@ -266,11 +255,20 @@
     }
 
+    private void UpdateIncludedResources() {
+      includedResources.Clear();
+      newIncludedResources.Clear();
+      foreach (var a in assignedResources) {
+        foreach (var r in HiveAdminClient.Instance.GetAvailableResourceDescendants(a.Id)) {
+          includedResources.Add(r);
+          newIncludedResources.Add(r);
+        }
+      }
+    }
+
     private void UpdateNewIncludedResources() {
       newIncludedResources.Clear();
       foreach (var a in newAssignedResources) {
-        if (resourceDescendants.ContainsKey(a.Id)) {
-          foreach (var r in resourceDescendants[a.Id]) {
-            newIncludedResources.Add(r);
-          }
+        foreach (var r in HiveAdminClient.Instance.GetAvailableResourceDescendants(a.Id)) {
+          newIncludedResources.Add(r);
         }
       }
@@ -325,5 +323,6 @@
           newNode.Checked = true;
           if(!HiveRoles.CheckAdminUserPermissions()) {
-            if(!projectAncestors[Content.Id].Any() || projectExclusiveResources.Contains(newResource)) {
+            if (!HiveAdminClient.Instance.GetAvailableProjectAncestors(Content.Id).Any() 
+              || projectExclusiveResources.Contains(newResource)) {
               newNode.ForeColor = SystemColors.GrayText;
               newNode.Text += IMMUTABLE_TAG;
@@ -401,65 +400,4 @@
     }
 
-    private void UpdateProjectGenealogy() {
-      projectAncestors.Clear();
-      projectDescendants.Clear();
-      var projects = HiveAdminClient.Instance.Projects;
-
-      foreach(var p in projects.Where(x => x.Id != Guid.Empty)) {
-        projectAncestors.Add(p.Id, new HashSet<Project>());
-        projectDescendants.Add(p.Id, new HashSet<Project>());
-      }
-
-      foreach (var p in projects.Where(x => x.Id != Guid.Empty)) {
-        var parentProjectId = p.ParentProjectId;
-        while (parentProjectId != null) {
-          var parent = projects.SingleOrDefault(x => x.Id == parentProjectId);
-          if (parent != null) {
-            projectAncestors[p.Id].Add(parent);
-            projectDescendants[parent.Id].Add(p);
-            parentProjectId = parent.ParentProjectId;
-          } else {
-            parentProjectId = null;
-          }
-        }
-      }
-    }
-
-    private void UpdateResourceGenealogy() {
-      resourceAncestors.Clear();
-      resourceDescendants.Clear();
-      var resources = HiveAdminClient.Instance.Resources;
-
-      foreach (var r in resources.Where(x => x.Id != Guid.Empty)) {
-        resourceAncestors.Add(r.Id, new HashSet<Resource>());
-        resourceDescendants.Add(r.Id, new HashSet<Resource>());
-      }
-
-      foreach (var r in resources.Where(x => x.Id != Guid.Empty)) {
-        var parentResourceId = r.ParentResourceId;
-        while (parentResourceId != null) {
-          var parent = resources.SingleOrDefault(x => x.Id == parentResourceId);
-          if (parent != null) {
-            resourceAncestors[r.Id].Add(parent);
-            resourceDescendants[parent.Id].Add(r);
-            parentResourceId = parent.ParentResourceId;
-          } else {
-            parentResourceId = null;
-          }
-        }
-      }
-
-      includedResources.Clear();
-      newIncludedResources.Clear();
-      foreach (var a in assignedResources) {
-        if (resourceDescendants.ContainsKey(a.Id)) {
-          foreach (var r in resourceDescendants[a.Id]) {
-            includedResources.Add(r);
-            newIncludedResources.Add(r);
-          }
-        }
-      }
-    }
-
     private bool IsAdmin() {
       return HiveRoles.CheckAdminUserPermissions();
Index: /branches/2839_HiveProjectManagement/HeuristicLab.Clients.Hive.Administrator/3.3/Views/ResourcesView.Designer.cs
===================================================================
--- /branches/2839_HiveProjectManagement/HeuristicLab.Clients.Hive.Administrator/3.3/Views/ResourcesView.Designer.cs	(revision 15921)
+++ /branches/2839_HiveProjectManagement/HeuristicLab.Clients.Hive.Administrator/3.3/Views/ResourcesView.Designer.cs	(revision 15922)
@@ -54,5 +54,5 @@
       this.btnRemoveGroup = new System.Windows.Forms.Button();
       this.btnAddGroup = new System.Windows.Forms.Button();
-      this.treeView = new System.Windows.Forms.TreeView();
+      this.treeView = new Hive.Views.TreeView.NoDoubleClickTreeView();
       this.tabSlaveGroup = new System.Windows.Forms.TabControl();
       this.tabDetails = new System.Windows.Forms.TabPage();
@@ -253,5 +253,5 @@
     private System.Windows.Forms.Button btnRemoveGroup;
     private System.Windows.Forms.Button btnAddGroup;
-    private System.Windows.Forms.TreeView treeView;
+    private HeuristicLab.Clients.Hive.Views.TreeView.NoDoubleClickTreeView treeView;
     private System.Windows.Forms.TabControl tabSlaveGroup;
     private System.Windows.Forms.TabPage tabDetails;
Index: /branches/2839_HiveProjectManagement/HeuristicLab.Clients.Hive.Administrator/3.3/Views/ResourcesView.cs
===================================================================
--- /branches/2839_HiveProjectManagement/HeuristicLab.Clients.Hive.Administrator/3.3/Views/ResourcesView.cs	(revision 15921)
+++ /branches/2839_HiveProjectManagement/HeuristicLab.Clients.Hive.Administrator/3.3/Views/ResourcesView.cs	(revision 15922)
@@ -231,5 +231,5 @@
       };
 
-      HiveAdminClient.Instance.UpdateResourceGenealogy(Content);
+      //HiveAdminClient.Instance.UpdateResourceGenealogy(Content);
       SelectedResource = group;
       Content.Add(group);
@@ -322,5 +322,6 @@
       }
 
-      HiveAdminClient.Instance.UpdateResourceGenealogy(Content);
+      // TODO
+      //HiveAdminClient.Instance.UpdateResourceGenealogy(Content);
       OnContentChanged();
     }
@@ -486,5 +487,5 @@
     private void CollapseSlaveOnlyNodes(TreeNode tn) {
       Resource r = (Resource)tn.Tag;
-      var descendants = HiveAdminClient.Instance.ResourceDescendants;
+      var descendants = GetResourceDescendants();
       if(descendants.ContainsKey(r.Id)) {
         if(descendants[r.Id].OfType<SlaveGroup>().Any()) {
@@ -493,4 +494,20 @@
         } else {
           tn.Collapse();
+        }
+      }
+    }
+
+    private void ExpandResourceNodesOfInterest(TreeNodeCollection nodes) {
+      foreach (TreeNode n in nodes) {
+        Resource r = (Resource)n.Tag;
+        if (n.Nodes.Count > 0) {
+          if (HiveClient.Instance.GetAvailableResourceDescendants(r.Id).OfType<SlaveGroup>().Any()) {
+            n.Expand();
+            ExpandResourceNodesOfInterest(n.Nodes);
+          } else {
+            n.Collapse();
+          }
+        } else {
+          n.Collapse();
         }
       }
@@ -560,10 +577,10 @@
       int childSlavesCount = 0;
       if (r.Id != Guid.Empty && r is SlaveGroup) {
-        var descendants = HiveAdminClient.Instance.ResourceDescendants;
+        var descendants = GetResourceDescendants();
         if (descendants.ContainsKey(r.Id)) {
           childSlavesCount = resources
             .OfType<Slave>()
             .Where(x => descendants[r.Id].Select(y => y.Id)
-            .Contains(x.Id))
+              .Contains(x.Id))
             .Count();
         }
@@ -659,4 +676,24 @@
     }
 
+
+    private Dictionary<Guid, HashSet<Resource>> GetResourceDescendants() {
+      var resourceDescendants = new Dictionary<Guid, HashSet<Resource>>();
+
+      foreach (var r in Content) resourceDescendants.Add(r.Id, new HashSet<Resource>());
+      foreach(var r in Content) {
+        var parentResourceId = r.ParentResourceId;
+        while(parentResourceId != null) {
+          var parent = Content.SingleOrDefault(x => x.Id == parentResourceId);
+          if(parent != null) {
+            resourceDescendants[parent.Id].Add(r);
+            parentResourceId = parent.ParentResourceId;
+          } else {
+            parentResourceId = null;
+          }
+        }
+      }
+      return resourceDescendants;
+    }
+    
     #endregion
   }
Index: /branches/2839_HiveProjectManagement/HeuristicLab.Clients.Hive.JobManager/3.3/Views/HiveResourceSelector.cs
===================================================================
--- /branches/2839_HiveProjectManagement/HeuristicLab.Clients.Hive.JobManager/3.3/Views/HiveResourceSelector.cs	(revision 15921)
+++ /branches/2839_HiveProjectManagement/HeuristicLab.Clients.Hive.JobManager/3.3/Views/HiveResourceSelector.cs	(revision 15922)
@@ -289,5 +289,5 @@
           if(project.Name.ToLower().Contains(currentSearchString.ToLower())) {
             filteredProjects.Add(project);
-            filteredProjects.UnionWith(Content.Where(p => HiveClient.Instance.ProjectAncestors[project.Id].Contains(p.Id)));
+            filteredProjects.UnionWith(Content.Where(p => HiveClient.Instance.GetAvailableProjectAncestors(project.Id).Select(x => x.Id).Contains(p.Id)));
           }
         }
@@ -448,5 +448,5 @@
     private void UpdateNewAssignedResources() {
       for(int i = newAssignedResources.Count-1; i>=0; i--) {
-        if(newAssignedResources.Intersect(HiveClient.Instance.GetAvailableParentResources(newAssignedResources.ElementAt(i).Id)).Any()) {
+        if(newAssignedResources.Intersect(HiveClient.Instance.GetAvailableResourceAncestors(newAssignedResources.ElementAt(i).Id)).Any()) {
           newAssignedResources.Remove(newAssignedResources.ElementAt(i));
         }
@@ -460,5 +460,5 @@
       if (JobId != Guid.Empty) {
         foreach (var item in assignedResources) {
-          foreach (var descendant in HiveClient.Instance.GetAvailableChildResources(item.Id)) {
+          foreach (var descendant in HiveClient.Instance.GetAvailableResourceDescendants(item.Id)) {
             includedResources.Add(descendant);
           }
@@ -467,5 +467,5 @@
 
       foreach (var item in newAssignedResources) {
-        foreach (var descendant in HiveClient.Instance.GetAvailableChildResources(item.Id)) {
+        foreach (var descendant in HiveClient.Instance.GetAvailableResourceDescendants(item.Id)) {
           newIncludedResources.Add(descendant);
         }
@@ -476,5 +476,5 @@
       newIncludedResources.Clear();
       foreach (var item in newAssignedResources) {
-        foreach (var descendant in HiveClient.Instance.GetAvailableChildResources(item.Id)) {
+        foreach (var descendant in HiveClient.Instance.GetAvailableResourceDescendants(item.Id)) {
           newIncludedResources.Add(descendant);
         }
@@ -598,6 +598,6 @@
         Resource r = (Resource)n.Tag;
         if(n.Nodes.Count > 0) {
-          if(HiveClient.Instance.GetAvailableChildResources(r.Id).OfType<SlaveGroup>().Any()
-            || HiveClient.Instance.GetAvailableChildResources(r.Id).OfType<Slave>().Intersect(assignedResources.Union(newAssignedResources)).Any()) {
+          if(HiveClient.Instance.GetAvailableResourceDescendants(r.Id).OfType<SlaveGroup>().Any()
+            || HiveClient.Instance.GetAvailableResourceDescendants(r.Id).OfType<Slave>().Intersect(assignedResources.Union(newAssignedResources)).Any()) {
             n.Expand();
             ExpandResourceNodesOfInterest(n.Nodes);
@@ -615,11 +615,9 @@
 
       Resource r = (Resource)tn.Tag;
-      if (HiveClient.Instance.ResourceDescendants.ContainsKey(r.Id)) {
-        if (HiveClient.Instance.GetAvailableChildResources(r.Id).OfType<SlaveGroup>().Any()) {
-          tn.Expand();
-          foreach (TreeNode n in tn.Nodes) CollapseSlaveOnlyNodes(n);
-        } else {
-          tn.Collapse();
-        }
+      if (HiveClient.Instance.GetAvailableResourceDescendants(r.Id).OfType<SlaveGroup>().Any()) {
+        tn.Expand();
+        foreach (TreeNode n in tn.Nodes) CollapseSlaveOnlyNodes(n);
+      } else {
+        tn.Collapse();
       }
     }
@@ -628,5 +626,5 @@
       HashSet<Slave> newAssignedSlaves = new HashSet<Slave>(newAssignedResources.OfType<Slave>());
       foreach (var slaveGroup in newAssignedResources.OfType<SlaveGroup>()) {
-        foreach (var slave in HiveClient.Instance.GetAvailableChildResources(slaveGroup.Id).OfType<Slave>()) {
+        foreach (var slave in HiveClient.Instance.GetAvailableResourceDescendants(slaveGroup.Id).OfType<Slave>()) {
           newAssignedSlaves.Add(slave);
         }
@@ -638,5 +636,5 @@
         var slaveGroup = resource as SlaveGroup;
         if (slaveGroup != null) {
-          selectedSlaves = new HashSet<Slave>(HiveClient.Instance.GetAvailableChildResources(slaveGroup.Id).OfType<Slave>());
+          selectedSlaves = new HashSet<Slave>(HiveClient.Instance.GetAvailableResourceDescendants(slaveGroup.Id).OfType<Slave>());
         } else {
           selectedSlaves = new HashSet<Slave>(new[] { resource as Slave });
Index: /branches/2839_HiveProjectManagement/HeuristicLab.Clients.Hive.Views/3.3/HeuristicLab.Clients.Hive.Views-3.3.csproj
===================================================================
--- /branches/2839_HiveProjectManagement/HeuristicLab.Clients.Hive.Views/3.3/HeuristicLab.Clients.Hive.Views-3.3.csproj	(revision 15921)
+++ /branches/2839_HiveProjectManagement/HeuristicLab.Clients.Hive.Views/3.3/HeuristicLab.Clients.Hive.Views-3.3.csproj	(revision 15922)
@@ -169,4 +169,7 @@
       <DependentUpon>StateLogView.cs</DependentUpon>
     </Compile>
+    <Compile Include="TreeView\NoDoubleClickTreeView.cs">
+      <SubType>Component</SubType>
+    </Compile>
     <None Include="Plugin.cs.frame" />
     <Compile Include="Plugin.cs" />
Index: /branches/2839_HiveProjectManagement/HeuristicLab.Clients.Hive.Views/3.3/TreeView/NoDoubleClickTreeView.cs
===================================================================
--- /branches/2839_HiveProjectManagement/HeuristicLab.Clients.Hive.Views/3.3/TreeView/NoDoubleClickTreeView.cs	(revision 15921)
+++ /branches/2839_HiveProjectManagement/HeuristicLab.Clients.Hive.Views/3.3/TreeView/NoDoubleClickTreeView.cs	(revision 15922)
@@ -1,5 +1,5 @@
 ﻿#region License Information
 /* HeuristicLab
- * Copyright (C) 2002-2016 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ * Copyright (C) 2002-2018 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
  *
  * This file is part of HeuristicLab.
@@ -24,4 +24,6 @@
 
 namespace HeuristicLab.Clients.Hive.Views.TreeView {
+  // Workaround for a well-known bug in TreeView
+  // cf. https://stackoverflow.com/questions/6130297/c-how-to-avoid-treenode-check-from-happening-on-a-double-click-event
   public class NoDoubleClickTreeView : System.Windows.Forms.TreeView {
     protected override void WndProc(ref Message m) {
Index: /branches/2839_HiveProjectManagement/HeuristicLab.Clients.Hive/3.3/HiveAdminClient.cs
===================================================================
--- /branches/2839_HiveProjectManagement/HeuristicLab.Clients.Hive/3.3/HiveAdminClient.cs	(revision 15921)
+++ /branches/2839_HiveProjectManagement/HeuristicLab.Clients.Hive/3.3/HiveAdminClient.cs	(revision 15922)
@@ -70,25 +70,43 @@
     }
 
-    private Dictionary<Guid, HashSet<Project>> projectAncestors;
-    public Dictionary<Guid, HashSet<Project>> ProjectAncestors {
+    //private Dictionary<Guid, HashSet<Project>> projectAncestors;
+    //public Dictionary<Guid, HashSet<Project>> ProjectAncestors {
+    //  get { return projectAncestors; }
+    //}
+
+    //private Dictionary<Guid, HashSet<Project>> projectDescendants;
+    //public Dictionary<Guid, HashSet<Project>> ProjectDescendants {
+    //  get { return projectDescendants; }
+    //}
+
+    //private Dictionary<Guid, HashSet<Resource>> resourceAncestors;
+    //public Dictionary<Guid, HashSet<Resource>> ResourceAncestors {
+    //  get { return resourceAncestors; }
+    //}
+
+    //private Dictionary<Guid, HashSet<Resource>> resourceDescendants;
+    //public Dictionary<Guid, HashSet<Resource>> ResourceDescendants {
+    //  get { return resourceDescendants; }
+    //}
+
+    private Dictionary<Guid, HashSet<Guid>> projectAncestors;
+    public Dictionary<Guid, HashSet<Guid>> ProjectAncestors {
       get { return projectAncestors; }
     }
 
-    private Dictionary<Guid, HashSet<Project>> projectDescendants;
-    public Dictionary<Guid, HashSet<Project>> ProjectDescendants {
+    private Dictionary<Guid, HashSet<Guid>> projectDescendants;
+    public Dictionary<Guid, HashSet<Guid>> ProjectDescendants {
       get { return projectDescendants; }
     }
 
-    private Dictionary<Guid, HashSet<Resource>> resourceAncestors;
-    public Dictionary<Guid, HashSet<Resource>> ResourceAncestors {
+    private Dictionary<Guid, HashSet<Guid>> resourceAncestors;
+    public Dictionary<Guid, HashSet<Guid>> ResourceAncestors {
       get { return resourceAncestors; }
     }
 
-    private Dictionary<Guid, HashSet<Resource>> resourceDescendants;
-    public Dictionary<Guid, HashSet<Resource>> ResourceDescendants {
+    private Dictionary<Guid, HashSet<Guid>> resourceDescendants;
+    public Dictionary<Guid, HashSet<Guid>> ResourceDescendants {
       get { return resourceDescendants; }
     }
-
-
     #endregion
 
@@ -117,8 +135,12 @@
         projectResourceAssignments = new ItemList<AssignedProjectResource>();
 
-        projectAncestors = new Dictionary<Guid, HashSet<Project>>();
-        projectDescendants = new Dictionary<Guid, HashSet<Project>>();
-        resourceAncestors = new Dictionary<Guid, HashSet<Resource>>();
-        resourceDescendants = new Dictionary<Guid, HashSet<Resource>>();
+        //projectAncestors = new Dictionary<Guid, HashSet<Project>>();
+        //projectDescendants = new Dictionary<Guid, HashSet<Project>>();
+        //resourceAncestors = new Dictionary<Guid, HashSet<Resource>>();
+        //resourceDescendants = new Dictionary<Guid, HashSet<Resource>>();
+        projectAncestors = new Dictionary<Guid, HashSet<Guid>>();
+        projectDescendants = new Dictionary<Guid, HashSet<Guid>>();
+        resourceAncestors = new Dictionary<Guid, HashSet<Guid>>();
+        resourceDescendants = new Dictionary<Guid, HashSet<Guid>>();
 
         HiveServiceLocator.Instance.CallHiveService(service => {
@@ -132,6 +154,6 @@
         });
 
-        UpdateResourceGenealogy(resources);
-        UpdateProjectGenealogy(projects);
+        UpdateResourceGenealogy();
+        UpdateProjectGenealogy();
       }
       catch {
@@ -143,51 +165,92 @@
     }
 
-    public void UpdateResourceGenealogy(IItemList<Resource> resources) {
+    //public void UpdateResourceGenealogy(IItemList<Resource> resources) {
+    //  resourceAncestors.Clear();
+    //  resourceDescendants.Clear();
+
+    //  foreach (var r in resources) {
+    //    resourceAncestors.Add(r.Id, new HashSet<Resource>());
+    //    resourceDescendants.Add(r.Id, new HashSet<Resource>());
+    //  }
+
+    //  foreach (var r in resources) {
+    //    var parentResourceId = r.ParentResourceId;
+    //    while (parentResourceId != null) {
+    //      var parent = resources.SingleOrDefault(x => x.Id == parentResourceId);
+    //      if (parent != null) {
+    //        resourceAncestors[r.Id].Add(parent);
+    //        resourceDescendants[parent.Id].Add(r);
+    //        parentResourceId = parent.ParentResourceId;
+    //      } else {
+    //        parentResourceId = null;
+    //      }
+    //    }
+    //  }
+    //}
+
+    //public void UpdateProjectGenealogy(IItemList<Project> projects) {
+    //  projectAncestors.Clear();
+    //  projectDescendants.Clear();
+
+    //  foreach (var p in projects) {
+    //    projectAncestors.Add(p.Id, new HashSet<Project>());
+    //    projectDescendants.Add(p.Id, new HashSet<Project>());
+    //  }
+
+    //  foreach (var p in projects) {
+    //    var parentProjectId = p.ParentProjectId;
+    //    while (parentProjectId != null) {
+    //      var parent = projects.SingleOrDefault(x => x.Id == parentProjectId);
+    //      if (parent != null) {
+    //        projectAncestors[p.Id].Add(parent);
+    //        projectDescendants[parent.Id].Add(p);
+    //        parentProjectId = parent.ParentProjectId;
+    //      } else {
+    //        parentProjectId = null;
+    //      }
+    //    }
+    //  }
+    //}
+
+    private void UpdateResourceGenealogy() {
       resourceAncestors.Clear();
       resourceDescendants.Clear();
 
-      foreach (var r in resources) {
-        resourceAncestors.Add(r.Id, new HashSet<Resource>());
-        resourceDescendants.Add(r.Id, new HashSet<Resource>());
-      }
-
-      foreach (var r in resources) {
-        var parentResourceId = r.ParentResourceId;
-        while (parentResourceId != null) {
-          var parent = resources.SingleOrDefault(x => x.Id == parentResourceId);
-          if (parent != null) {
-            resourceAncestors[r.Id].Add(parent);
-            resourceDescendants[parent.Id].Add(r);
-            parentResourceId = parent.ParentResourceId;
-          } else {
-            parentResourceId = null;
-          }
-        }
-      }
-    }
-
-    public void UpdateProjectGenealogy(IItemList<Project> projects) {
+      // fetch resource ancestor set
+      HiveServiceLocator.Instance.CallHiveService(service => {
+        var ra = service.GetResourceGenealogy();
+        ra.Keys.ToList().ForEach(k => resourceAncestors.Add(k, new HashSet<Guid>()));
+        resourceAncestors.Keys.ToList().ForEach(k => resourceAncestors[k].UnionWith(ra[k]));
+      });
+
+      // build resource descendant set
+      resourceAncestors.Keys.ToList().ForEach(k => resourceDescendants.Add(k, new HashSet<Guid>()));
+      foreach (var ra in resourceAncestors) {
+        foreach (var ancestor in ra.Value) {
+          resourceDescendants[ancestor].Add(ra.Key);
+        }
+      }
+    }
+
+    private void UpdateProjectGenealogy() {
       projectAncestors.Clear();
       projectDescendants.Clear();
 
-      foreach (var p in projects) {
-        projectAncestors.Add(p.Id, new HashSet<Project>());
-        projectDescendants.Add(p.Id, new HashSet<Project>());
-      }
-
-      foreach (var p in projects) {
-        var parentProjectId = p.ParentProjectId;
-        while (parentProjectId != null) {
-          var parent = projects.SingleOrDefault(x => x.Id == parentProjectId);
-          if (parent != null) {
-            projectAncestors[p.Id].Add(parent);
-            projectDescendants[parent.Id].Add(p);
-            parentProjectId = parent.ParentProjectId;
-          } else {
-            parentProjectId = null;
-          }
-        }
-      }
-    }
+      // fetch project ancestor list
+      HiveServiceLocator.Instance.CallHiveService(service => {
+        var pa = service.GetProjectGenealogy();
+        pa.Keys.ToList().ForEach(k => projectAncestors.Add(k, new HashSet<Guid>()));
+        projectAncestors.Keys.ToList().ForEach(k => projectAncestors[k].UnionWith(pa[k]));
+      });
+
+      // build project descendant list
+      projectAncestors.Keys.ToList().ForEach(k => projectDescendants.Add(k, new HashSet<Guid>()));
+      foreach (var pa in projectAncestors) {
+        foreach (var ancestor in pa.Value) {
+          projectDescendants[ancestor].Add(pa.Key);
+        }
+      }
+    }
+
     #endregion
 
@@ -268,4 +331,24 @@
 
     #region Helper
+    public IEnumerable<Project> GetAvailableProjectAncestors(Guid id) {
+      if (projectAncestors.ContainsKey(id)) return projects.Where(x => projectAncestors[id].Contains(x.Id));
+      else return Enumerable.Empty<Project>();
+    }
+
+    public IEnumerable<Project> GetAvailableProjectDescendants(Guid id) {
+      if(projectDescendants.ContainsKey(id)) return projects.Where(x => projectDescendants[id].Contains(x.Id));
+      else return Enumerable.Empty<Project>();
+    }
+
+    public IEnumerable<Resource> GetAvailableResourceAncestors(Guid id) {
+      if (resourceAncestors.ContainsKey(id)) return resources.Where(x => resourceAncestors[id].Contains(x.Id));
+      else return Enumerable.Empty<Resource>();
+    }
+
+    public IEnumerable<Resource> GetAvailableResourceDescendants(Guid id) {
+      if (resourceDescendants.ContainsKey(id)) return resources.Where(x => resourceDescendants[id].Contains(x.Id));
+      else return Enumerable.Empty<Resource>();
+    }
+
     public bool CheckAccessToAdminAreaGranted() {
       if(projects != null) {
@@ -286,5 +369,5 @@
         return true;
       } else if(resourceAncestors.ContainsKey(res.Id)) {
-        return resourceAncestors[res.Id].Where(x => x.OwnerUserId == userId).Any();
+        return GetAvailableResourceAncestors(res.Id).Where(x => x.OwnerUserId == userId).Any();
       }
 
@@ -298,5 +381,5 @@
         return true;
       } else if (projectAncestors.ContainsKey(pro.Id)) {
-        return projectAncestors[pro.Id].Where(x => x.OwnerUserId == userId).Any();
+        return GetAvailableProjectAncestors(pro.Id).Where(x => x.OwnerUserId == userId).Any();
       }
 
@@ -308,5 +391,5 @@
 
       if(projectAncestors.ContainsKey(pro.Id)) {
-        return projectAncestors[pro.Id].Where(x => x.OwnerUserId == userId).Any();
+        return GetAvailableProjectAncestors(pro.Id).Where(x => x.OwnerUserId == userId).Any();
       }
 
@@ -327,5 +410,5 @@
       } else if(parent != null && projectDescendants.ContainsKey(child.Id)) {
         // ... if the new parent is among the moved project's descendants
-        changePossible = !projectDescendants[child.Id].Where(x => x.Id == parent.Id).Any();
+        changePossible = !GetAvailableProjectDescendants(child.Id).Where(x => x.Id == parent.Id).Any();
       }
 
@@ -350,5 +433,5 @@
       } else if (parent != null && resourceDescendants.ContainsKey(child.Id)) {
         // ... or if the new parent is among the moved resource's descendants
-        changePossible = !resourceDescendants[child.Id].Where(x => x.Id == parent.Id).Any();
+        changePossible = !GetAvailableResourceDescendants(child.Id).Where(x => x.Id == parent.Id).Any();
       }
 
Index: /branches/2839_HiveProjectManagement/HeuristicLab.Clients.Hive/3.3/HiveClient.cs
===================================================================
--- /branches/2839_HiveProjectManagement/HeuristicLab.Clients.Hive/3.3/HiveClient.cs	(revision 15921)
+++ /branches/2839_HiveProjectManagement/HeuristicLab.Clients.Hive/3.3/HiveClient.cs	(revision 15922)
@@ -239,20 +239,23 @@
     }
 
-    public IEnumerable<Project> GetAvailableParentProjects(Guid id) {
-      return projects.Where(x => projectAncestors[id].Contains(x.Id));
-    }
-
-    public IEnumerable<Project> GetAvailableChildProjects(Guid id) {
-      return projects.Where(x => projectDescendants[id].Contains(x.Id));
-    }
-
-    public IEnumerable<Resource> GetAvailableParentResources(Guid id) {
-      return resources.Where(x => resourceAncestors[id].Contains(x.Id));
-    }
-
-    public IEnumerable<Resource> GetAvailableChildResources(Guid id) {
-      return resources.Where(x => resourceDescendants[id].Contains(x.Id));
-    }
-
+    public IEnumerable<Project> GetAvailableProjectAncestors(Guid id) {
+      if (projectAncestors.ContainsKey(id)) return projects.Where(x => projectAncestors[id].Contains(x.Id));
+      else return Enumerable.Empty<Project>();
+    }
+
+    public IEnumerable<Project> GetAvailableProjectDescendants(Guid id) {
+      if (projectDescendants.ContainsKey(id)) return projects.Where(x => projectDescendants[id].Contains(x.Id));
+      else return Enumerable.Empty<Project>();
+    }
+
+    public IEnumerable<Resource> GetAvailableResourceAncestors(Guid id) {
+      if (resourceAncestors.ContainsKey(id)) return resources.Where(x => resourceAncestors[id].Contains(x.Id));
+      else return Enumerable.Empty<Resource>();
+    }
+
+    public IEnumerable<Resource> GetAvailableResourceDescendants(Guid id) {
+      if (resourceDescendants.ContainsKey(id)) return resources.Where(x => resourceDescendants[id].Contains(x.Id));
+      else return Enumerable.Empty<Resource>();
+    }
     #endregion
 
