Index: /branches/HiveProjectManagement/HeuristicLab.Clients.Hive.Administrator/3.3/Views/ProjectsView.cs
===================================================================
--- /branches/HiveProjectManagement/HeuristicLab.Clients.Hive.Administrator/3.3/Views/ProjectsView.cs	(revision 15741)
+++ /branches/HiveProjectManagement/HeuristicLab.Clients.Hive.Administrator/3.3/Views/ProjectsView.cs	(revision 15742)
@@ -40,10 +40,10 @@
     private const int greenFlagImageIndex = 0;
     private const int redFlagImageIndex = 1;
+
     private readonly Color changedColor = Color.FromArgb(255, 87, 191, 193); // #57bfc1
     private readonly Color selectedColor = Color.FromArgb(255, 240, 194, 59); // #f0c23b
+    private Project selectedProject = null;
 
     private readonly object locker = new object();
-
-    private Project selectedProject = null;
 
     public new IItemList<Project> Content {
@@ -173,6 +173,5 @@
     private async void ProjectsView_Load(object sender, EventArgs e) {
       await SecurityExceptionUtil.TryAsyncAndReportSecurityExceptions(
-        action: () => UpdateProjects(),
-        finallyCallback: () => Content = HiveAdminClient.Instance.Projects);
+        action: () => UpdateProjects());
     }
 
@@ -186,5 +185,4 @@
         action: () => UpdateProjects(),
         finallyCallback: () => {
-          Content = HiveAdminClient.Instance.Projects;
           refreshButton.Enabled = true;
         });
@@ -193,4 +191,14 @@
     private void addButton_Click(object sender, EventArgs e) {
       Guid? parentProjectId = null;
+
+      if (selectedProject != null && selectedProject.Id == Guid.Empty) {
+        MessageBox.Show(
+          "You cannot add a project to a not yet stored project.",
+          "HeuristicLab Hive Administrator",
+          MessageBoxButtons.OK,
+          MessageBoxIcon.Information);
+        return;
+      }
+
       if (selectedProject != null) parentProjectId = selectedProject.Id;
       var project = new Project {
@@ -199,8 +207,12 @@
         ParentProjectId = parentProjectId
       };
+
+      selectedProject = project;
       Content.Add(project);
     }
 
     private async void removeButton_Click(object sender, EventArgs e) {
+      if (selectedProject == null) return;
+
       lock (locker) {
         if (!removeButton.Enabled) return;
@@ -208,10 +220,26 @@
       }
 
-      var selectedNode = projectsTreeView.SelectedNode;
-      if (selectedNode == null || selectedNode.Tag == null) return;
-
-      var project = (Project)selectedNode.Tag;
+      if(!IsAdmin() 
+        && HiveAdminClient.Instance.CheckOwnershipOfParentProject(selectedProject, 
+          UserInformation.Instance.User.Id)) {
+        MessageBox.Show(
+          "Only subprojects of owned projects can be deleted.",
+          "HeuristicLab Hive Administrator",
+          MessageBoxButtons.OK,
+          MessageBoxIcon.Error);
+        return;
+      }
+
+      if (!IsAdmin() && Content.Any(x => x.ParentProjectId == selectedProject.Id)) {
+        MessageBox.Show(
+          "Only empty projects can be deleted.",
+          "HeuristicLab Hive Administrator",
+          MessageBoxButtons.OK,
+          MessageBoxIcon.Error);
+        return;
+      }
+
       var result = MessageBox.Show(
-        "Do you really want to delete " + project.Name + "?",
+        "Do you really want to delete " + selectedProject.Name + "?",
         "HeuristicLab Hive Administrator",
         MessageBoxButtons.YesNo,
@@ -219,18 +247,9 @@
 
       if (result == DialogResult.Yes) {
-        if (Content.Any(x => x.ParentProjectId == project.Id)) {
-          MessageBox.Show(
-            "Only empty projects can be deleted.",
-            "HeuristicLab Hive Administrator",
-            MessageBoxButtons.OK,
-            MessageBoxIcon.Error);
-        } else {
-          await SecurityExceptionUtil.TryAsyncAndReportSecurityExceptions(
-            action: () => RemoveProject(project),
-            finallyCallback: () => {
-              Content.Remove(project);
-              removeButton.Enabled = true;
-            });
-        }
+        await SecurityExceptionUtil.TryAsyncAndReportSecurityExceptions(
+          action: () => RemoveProject(selectedProject),
+          finallyCallback: () => {
+            removeButton.Enabled = true;
+          });
       }
     }
@@ -247,4 +266,5 @@
           foreach (var project in projectsToSave)
             project.Store();
+          UpdateProjects();
         },
         finallyCallback: () => saveProjectButton.Enabled = true);
@@ -254,9 +274,5 @@
 
     private void projectsTreeView_AfterSelect(object sender, TreeViewEventArgs e) {
-      selectedProject = (Project)e.Node.Tag;
-      ReColorTreeNodes(projectsTreeView.Nodes, selectedColor, Color.Transparent, true);
-      e.Node.BackColor = selectedColor;
-      e.Node.Text += " [selected]";
-      
+      ChangeSelectedProjectNode(e.Node);
 
       //if (projectView.Content != null)
@@ -269,16 +285,4 @@
       //if (selectedProject != null)
       //  selectedProject.PropertyChanged += ProjectViewContent_PropertyChanged;
-
-      //if (IsAuthorized(selectedProject)) {
-      //  if (!tabControl.TabPages.Contains(permissionsTabPage))
-      //    tabControl.TabPages.Add(permissionsTabPage);
-      //  if (!tabControl.TabPages.Contains(resourcesTabPage))
-      //    tabControl.TabPages.Add(resourcesTabPage);
-      //} else {
-      //  if (tabControl.TabPages.Contains(permissionsTabPage))
-      //    tabControl.TabPages.Remove(permissionsTabPage);
-      //  if (tabControl.TabPages.Contains(resourcesTabPage))
-      //    tabControl.TabPages.Remove(resourcesTabPage);
-      //}
     }
 
@@ -286,4 +290,6 @@
       var sourceNode = (TreeNode)e.Data.GetData(typeof(TreeNode));
       if (sourceNode == null) return;
+      var sourceResource = ((Project)sourceNode.Tag);
+      if (sourceResource == null) return;
 
       var treeView = (TreeView)sender;
@@ -294,18 +300,31 @@
 
       if (sourceNode == targetNode) return;
-
-      if (sourceNode.Parent == null)
+      var targetProject = (targetNode != null) ? (Project)targetNode.Tag : null;
+
+      if(targetProject != null && targetProject.Id == Guid.Empty) {
+        MessageBox.Show(
+          "You cannot drag projects to a not yet stored project.",
+          "HeuristicLab Hive Administrator",
+          MessageBoxButtons.OK,
+          MessageBoxIcon.Information);
+            return;
+      }
+
+      if (sourceNode.Parent == null) {
         treeView.Nodes.Remove(sourceNode);
-      else {
+      } else {
         sourceNode.Parent.Nodes.Remove(sourceNode);
-        ((Project)sourceNode.Tag).ParentProjectId = null;
+        sourceResource.ParentProjectId = null;
       }
 
       if (targetNode == null) {
         treeView.Nodes.Add(sourceNode);
-      } else {
+      } else if(targetProject.Id != Guid.Empty) {
         targetNode.Nodes.Add(sourceNode);
-        ((Project)sourceNode.Tag).ParentProjectId = ((Project)targetNode.Tag).Id;
-      }
+        sourceResource.ParentProjectId = targetProject.Id;
+      }
+
+      selectedProject = sourceResource;
+      OnContentChanged();
     }
 
@@ -330,14 +349,30 @@
 
     #region Helpers
-    private void ReColorTreeNodes(TreeNodeCollection nodes, Color c1, Color c2, bool resetText) {
-      foreach(TreeNode n in nodes) {
-        if(n.BackColor.Equals(c1)) {
+    private void ResetTreeNodes(TreeNodeCollection nodes, Color c1, Color c2, bool resetText) {
+      foreach (TreeNode n in nodes) {
+        var pro = ((Project)n.Tag);
+        if (n.BackColor.Equals(c1)) {
           n.BackColor = c2;
-          if (resetText) n.Text = ((Project)n.Tag).Name;
+        }
+        if (resetText) {
+          n.Text = pro.Name;
+
+          if (pro.Id == Guid.Empty) {
+            n.Text += " [not stored]";
+          } else if (pro.Modified) {
+            n.Text += " [changes not stored]";
+          }
         }
         if (n.Nodes.Count > 0) {
-          ReColorTreeNodes(n.Nodes, c1, c2, resetText);
-        }
-      }
+          ResetTreeNodes(n.Nodes, c1, c2, resetText);
+        }
+      }
+    }
+
+    private void ChangeSelectedProjectNode(TreeNode projectNode) {
+      selectedProject = (Project)projectNode.Tag;
+      ResetTreeNodes(projectsTreeView.Nodes, selectedColor, Color.Transparent, true);
+      projectNode.BackColor = selectedColor;
+      projectNode.Text += " [selected]";
     }
 
@@ -354,5 +389,5 @@
 
       var stack = new Stack<Project>(mainProjects.OrderByDescending(x => x.Name));
-      Project top = null;
+      if (selectedProject != null) selectedProject = projects.Where(x => x.Id == selectedProject.Id).FirstOrDefault();
 
       TreeNode currentNode = null;
@@ -362,10 +397,21 @@
         var newProject = stack.Pop();
         var newNode = new TreeNode(newProject.Name) { Tag = newProject };
-        if (top == null) {
-          top = newProject;
+
+        if (newProject.Id == Guid.Empty) {
+          newNode.Text += " [not stored]";
+        } else if(newProject.Modified) {
+          newNode.Text += " [changes not stored]";
+        }
+        if (selectedProject == null) {
+          selectedProject = newProject;
+        }
+        if (newProject.Id == selectedProject.Id) {
           newNode.BackColor = selectedColor;
           newNode.Text += " [selected]";
         }
 
+        // search for parent node of newNode and save in currentNode
+        // necessary since newNodes (stack top items) might be siblings
+        // or grand..grandparents of previous node (currentNode)
         while (currentNode != null && newProject.ParentProjectId != currentProject.Id) {
           currentNode = currentNode.Parent;
@@ -396,5 +442,5 @@
       projectsTreeView.ExpandAll();
 
-      return top;
+      return selectedProject;
     }
 
@@ -402,4 +448,5 @@
       try {
         HiveAdminClient.Instance.Refresh();
+        Content = HiveAdminClient.Instance.Projects;
       } catch (AnonymousUserException) {
         ShowHiveInformationDialog();
@@ -408,6 +455,9 @@
 
     private void RemoveProject(Project project) {
+      if (project == null || project.Id == Guid.Empty) return;
+
       try {
         HiveAdminClient.Delete(project);
+        Content.Remove(selectedProject);
       } catch (AnonymousUserException) {
         ShowHiveInformationDialog();
@@ -420,4 +470,8 @@
     }
 
+    private bool IsAdmin() {
+      return HiveRoles.CheckAdminUserPermissions();
+    }
+
     private void ShowHiveInformationDialog() {
       if (InvokeRequired) Invoke((Action)ShowHiveInformationDialog);
Index: /branches/HiveProjectManagement/HeuristicLab.Clients.Hive.Administrator/3.3/Views/ResourceView.cs
===================================================================
--- /branches/HiveProjectManagement/HeuristicLab.Clients.Hive.Administrator/3.3/Views/ResourceView.cs	(revision 15741)
+++ /branches/HiveProjectManagement/HeuristicLab.Clients.Hive.Administrator/3.3/Views/ResourceView.cs	(revision 15742)
@@ -59,4 +59,5 @@
       base.SetEnabledStateOfControls();
       bool enabled = Content != null && !Locked;
+      idTextBox.ReadOnly = true;
       nameTextBox.ReadOnly = !enabled;
       descriptionTextBox.ReadOnly = !enabled;
Index: /branches/HiveProjectManagement/HeuristicLab.Clients.Hive.Administrator/3.3/Views/ResourcesView.Designer.cs
===================================================================
--- /branches/HiveProjectManagement/HeuristicLab.Clients.Hive.Administrator/3.3/Views/ResourcesView.Designer.cs	(revision 15741)
+++ /branches/HiveProjectManagement/HeuristicLab.Clients.Hive.Administrator/3.3/Views/ResourcesView.Designer.cs	(revision 15742)
@@ -157,4 +157,5 @@
       this.treeView.TabIndex = 0;
       this.treeView.ItemDrag += new System.Windows.Forms.ItemDragEventHandler(this.treeSlaveGroup_ItemDrag);
+      this.treeView.BeforeSelect += new System.Windows.Forms.TreeViewCancelEventHandler(this.treeSlaveGroup_BeforeSelect);
       this.treeView.AfterSelect += new System.Windows.Forms.TreeViewEventHandler(this.treeSlaveGroup_AfterSelect);
       this.treeView.DragDrop += new System.Windows.Forms.DragEventHandler(this.treeSlaveGroup_DragDrop);
Index: /branches/HiveProjectManagement/HeuristicLab.Clients.Hive.Administrator/3.3/Views/ResourcesView.cs
===================================================================
--- /branches/HiveProjectManagement/HeuristicLab.Clients.Hive.Administrator/3.3/Views/ResourcesView.cs	(revision 15741)
+++ /branches/HiveProjectManagement/HeuristicLab.Clients.Hive.Administrator/3.3/Views/ResourcesView.cs	(revision 15742)
@@ -43,5 +43,8 @@
     public const string ungroupedGroupDescription = "Contains slaves that are not assigned to any group.";
 
-    private readonly Color ownedResourceColor = Color.LightGreen;
+    private readonly Color changedColor = Color.FromArgb(255, 87, 191, 193); // #57bfc1
+    private readonly Color selectedColor = Color.FromArgb(255, 240, 194, 59); // #f0c23b
+    private Resource selectedResource = null;
+
     private readonly object locker = new object();
 
@@ -98,9 +101,9 @@
     protected override void SetEnabledStateOfControls() {
       base.SetEnabledStateOfControls();
-      bool enabled = Content != null && !Locked;
+      bool enabled = Content != null && !Locked && IsAdmin();
       btnAddGroup.Enabled = enabled;
       btnRemoveGroup.Enabled = enabled;
       btnSave.Enabled = enabled;
-      scheduleView.SetEnabledStateOfSchedule(enabled && IsAuthorized((Resource)viewHost.Content));
+      scheduleView.SetEnabledStateOfSchedule(enabled && IsAdmin()); // IsAuthorized((Resource)viewHost.Content));
     }
     #endregion
@@ -184,12 +187,35 @@
 
     private void btnAddGroup_Click(object sender, EventArgs e) {
+      Guid? parentResourceId = null;
+      if(!IsAdmin()) {
+        MessageBox.Show(
+          "You have no permission to add a resource group.",
+          "HeuristicLab Hive Administrator",
+          MessageBoxButtons.OK,
+          MessageBoxIcon.Information);
+        return;
+      } else if(selectedResource != null && selectedResource.Id == Guid.Empty) {
+        MessageBox.Show(
+          "You cannot add a resource group to a not yet stored group.",
+          "HeuristicLab Hive Administrator",
+          MessageBoxButtons.OK,
+          MessageBoxIcon.Information);
+        return;
+      }
+      
+      if (selectedResource != null && selectedResource is SlaveGroup) parentResourceId = selectedResource.Id;
       var group = new SlaveGroup {
         Name = "New Group",
-        OwnerUserId = UserInformation.Instance.User.Id
+        OwnerUserId = UserInformation.Instance.User.Id,
+        ParentResourceId = parentResourceId
       };
+
+      selectedResource = group;
       Content.Add(group);
     }
 
     private async void btnRemoveGroup_Click(object sender, EventArgs e) {
+      if (selectedResource == null) return;
+
       lock (locker) {
         if (!btnRemoveGroup.Enabled) return;
@@ -197,7 +223,34 @@
       }
 
-      await SecurityExceptionUtil.TryAsyncAndReportSecurityExceptions(
-        action: () => RemoveResource(),
-        finallyCallback: () => btnRemoveGroup.Enabled = true);
+      if (!IsAdmin()) {
+        MessageBox.Show(
+          "You have no permission to delete resources.",
+          "HeuristicLab Hive Administrator",
+          MessageBoxButtons.OK,
+          MessageBoxIcon.Information);
+        return;
+      }
+
+      if (Content.Any(x => x.ParentResourceId == selectedResource.Id)) {
+        MessageBox.Show(
+          "Only empty resources can be deleted.",
+          "HeuristicLab Hive Administrator",
+          MessageBoxButtons.OK,
+          MessageBoxIcon.Error);
+        return;
+      }
+
+      var result = MessageBox.Show(
+        "Do you really want to delete " + selectedResource.Name + "?",
+        "HeuristicLab Hive Administrator",
+        MessageBoxButtons.YesNo,
+        MessageBoxIcon.Question);
+      if (result == DialogResult.Yes) {
+        await SecurityExceptionUtil.TryAsyncAndReportSecurityExceptions(
+          action: () => RemoveResource(selectedResource),
+          finallyCallback: () => {
+            btnRemoveGroup.Enabled = true;
+          });
+      } 
     }
 
@@ -213,13 +266,21 @@
           foreach (var resource in resourcesToSave)
             resource.Store();
+          UpdateResources();
         },
         finallyCallback: () => btnSave.Enabled = true);
+
+      OnContentChanged();
+    }
+
+    private void treeSlaveGroup_BeforeSelect(object sender, TreeViewCancelEventArgs e) {
+      if (((Resource)e.Node.Tag).Name == ungroupedGroupName) e.Cancel = true;
     }
 
     private async void treeSlaveGroup_AfterSelect(object sender, TreeViewEventArgs e) {
-      var selectedResource = (Resource)e.Node.Tag;
-
-      if (viewHost.Content != null && viewHost.Content is SlaveGroup)
-        ((SlaveGroup)viewHost.Content).PropertyChanged -= SlaveViewContent_PropertyChanged;
+      ChangeSelectedResourceNode(e.Node);
+      SetEnabledStateOfControlsForSelectedResource();
+
+      //if (viewHost.Content != null && viewHost.Content is SlaveGroup)
+      //  ((SlaveGroup)viewHost.Content).PropertyChanged -= SlaveViewContent_PropertyChanged;
 
       viewHost.Content = selectedResource;
@@ -229,14 +290,10 @@
         finallyCallback: () => scheduleView.Content = HiveAdminClient.Instance.Downtimes);
 
-      if (selectedResource != null && selectedResource is SlaveGroup)
-        selectedResource.PropertyChanged += SlaveViewContent_PropertyChanged;
-
-      if (IsAuthorized(selectedResource)) {
-        if (!tabSlaveGroup.TabPages.Contains(tabSchedule))
-          tabSlaveGroup.TabPages.Add(tabSchedule);
-      } else {
-        if (tabSlaveGroup.TabPages.Contains(tabSchedule))
-          tabSlaveGroup.TabPages.Remove(tabSchedule);
-      }
+      //if (selectedResource != null && selectedResource is SlaveGroup)
+      //  selectedResource.PropertyChanged += SlaveViewContent_PropertyChanged;
+
+      bool locked = !IsAdmin();
+      viewHost.Locked = locked;
+      scheduleView.Locked = locked;
     }
 
@@ -244,4 +301,6 @@
       var sourceNode = (TreeNode)e.Data.GetData(typeof(TreeNode));
       if (sourceNode == null) return;
+      var sourceResource = ((Resource)sourceNode.Tag);
+      if (sourceResource == null) return;
 
       var treeView = (TreeView)sender;
@@ -252,12 +311,34 @@
 
       if (sourceNode == targetNode) return;
-
-      if (targetNode.Text == ungroupedGroupName || targetNode.Parent != null && targetNode.Parent.Text == ungroupedGroupName) {
-        MessageBox.Show(
-          string.Format(@"You cannot drag resources to group ""{0}"". This group only contains slaves which have not been assigned to a real group yet.", ungroupedGroupName),
+      var targetResource = (targetNode != null) ? (Resource)targetNode.Tag : null;
+
+      if (!IsAdmin()) {
+        MessageBox.Show(
+          "You cannot drag resources. This is solely granted for HeuristicLab Hive Administrators.",
           "HeuristicLab Hive Administrator",
           MessageBoxButtons.OK,
           MessageBoxIcon.Information);
         return;
+      } else if (targetResource != null && targetResource is Slave) {
+        MessageBox.Show(
+          "You cannot drag resources on to a slave.",
+          "HeuristicLab Hive Administrator",
+          MessageBoxButtons.OK,
+          MessageBoxIcon.Information);
+        return;
+      } else if(targetResource != null && targetResource.Id == Guid.Empty) {
+        MessageBox.Show(
+          "You cannot drag resources to a not yet stored resource group.",
+          "HeuristicLab Hive Administrator",
+          MessageBoxButtons.OK,
+          MessageBoxIcon.Information);
+            return;
+      } else if (targetNode != null && (targetNode.Text == ungroupedGroupName || targetNode.Parent != null && targetNode.Parent.Text == ungroupedGroupName)) {
+        MessageBox.Show(
+          string.Format(@"You cannot drag resources to group ""{0}"". This group only contains slaves which have not been assigned to a real group yet.", ungroupedGroupName),
+          "HeuristicLab Hive Administrator",
+          MessageBoxButtons.OK,
+          MessageBoxIcon.Information);
+        return;
       }
 
@@ -266,18 +347,21 @@
       else {
         sourceNode.Parent.Nodes.Remove(sourceNode);
-        ((Resource)sourceNode.Tag).ParentResourceId = null;
+        sourceResource.ParentResourceId = null;
       }
 
       if (targetNode == null) {
         treeView.Nodes.Add(sourceNode);
-      } else {
+      } else if(targetResource.Id != Guid.Empty) {
         targetNode.Nodes.Add(sourceNode);
-        ((Resource)sourceNode.Tag).ParentResourceId = ((Project)targetNode.Tag).Id;
-      }
+        sourceResource.ParentResourceId = targetResource.Id;
+      }
+
+      selectedResource = sourceResource;
+      OnContentChanged();
     }
 
     private void treeSlaveGroup_ItemDrag(object sender, ItemDragEventArgs e) {
       TreeNode sourceNode = (TreeNode)e.Item;
-      if (IsAuthorized((Resource)sourceNode.Tag))
+      if (IsAdmin())
         DoDragDrop(sourceNode, DragDropEffects.All);
     }
@@ -297,9 +381,31 @@
 
     #region Helpers
+    private void ResetTreeNodes(TreeNodeCollection nodes, Color c1, Color c2, bool resetText) {
+      foreach (TreeNode n in nodes) {
+        var res = ((Resource)n.Tag);
+        if (n.BackColor.Equals(c1)) {
+          n.BackColor = c2;
+        }
+        if (resetText) {
+          n.Text = res.Name;
+
+          if (res.Id == Guid.Empty && res.Name != ungroupedGroupName) {
+            n.Text += " [not stored]";
+          } else if (res.Modified && res.Name != ungroupedGroupName) {
+            n.Text += " [changes not stored]";
+          }
+        }
+        if (n.Nodes.Count > 0) {
+          ResetTreeNodes(n.Nodes, c1, c2, resetText);
+        }
+      }
+    }
+
     private Resource BuildResourceTree(IEnumerable<Resource> resources) {
       treeView.Nodes.Clear();
       if (!resources.Any()) return null;
 
-      var mainResources = new HashSet<Resource>(resources.OfType<SlaveGroup>().Where(x => x.ParentResourceId == null));
+      var mainResources = new HashSet<Resource>(resources.OfType<SlaveGroup>()
+        .Where(x => x.ParentResourceId == null));
       var parentedMainResources = new HashSet<Resource>(resources.OfType<SlaveGroup>()
         .Where(x => x.ParentResourceId.HasValue && !resources.Select(y => y.Id).Contains(x.ParentResourceId.Value)));
@@ -308,5 +414,6 @@
 
       var stack = new Stack<Resource>(mainResources.OrderByDescending(x => x.Name));
-      Resource top = null;
+      if (selectedResource != null) selectedResource = resources.Where(x => x.Id == selectedResource.Id).FirstOrDefault();
+      //bool nodeSelected = false;
 
       TreeNode currentNode = null;
@@ -314,12 +421,24 @@
 
       while(stack.Any()) {
-        if (top == null) top = stack.Peek();
         var newResource = stack.Pop();
         var newNode = new TreeNode(newResource.Name) { Tag = newResource };
+
+        if(newResource.Id == Guid.Empty) {
+          newNode.Text += " [not stored]";
+        } else if(newResource.Modified) {
+          newNode.Text += " [changes not stored]";
+        }
+        if (selectedResource == null) {
+          selectedResource = newResource;
+        }
+        if (newResource.Id == selectedResource.Id) {
+          newNode.BackColor = selectedColor;
+          newNode.Text += " [selected]";
+        }
 
         // search for parent node of newNode and save in currentNode
         // necessary since newNodes (stack top items) might be siblings
         // or grand..grandparents of previous node (currentNode)
-        while(currentNode != null && newResource.ParentResourceId != currentResource.Id) {
+        while (currentNode != null && newResource.ParentResourceId != currentResource.Id) {
           currentNode = currentNode.Parent;
           currentResource = currentNode == null ? null : (Resource)currentNode.Tag;
@@ -363,4 +482,16 @@
         var slaveNode = new TreeNode(slave.Name) { Tag = slave };
         ungroupedNode.Nodes.Add(slaveNode);
+        if(selectedResource == null) {
+          selectedResource = slave;
+        }
+        if (slave.Id == Guid.Empty) {
+          slaveNode.Text += " [not stored]";
+        } else if (slave.Modified) {
+          slaveNode.Text += " [changes not stored]";
+        }
+        if (slave.Id == selectedResource.Id) {
+          slaveNode.BackColor = selectedColor;
+          slaveNode.Text += " [selected]";
+        }
       }
 
@@ -368,5 +499,5 @@
       treeView.ExpandAll();
 
-      return top;
+      return selectedResource;
     }
 
@@ -411,35 +542,20 @@
 
     private void UpdateResources() {
-      HiveAdminClient.Instance.Refresh();
-      Content = HiveAdminClient.Instance.Resources;
-    }
-
-    private void RemoveResource() {
-      var selectedNode = treeView.SelectedNode;
-      if (selectedNode == null || selectedNode.Tag == null) return;
-
-      var resource = (Resource)selectedNode.Tag;
-      var result = MessageBox.Show(
-        "Do you really want to delete " + resource.Name + "?",
-        "HeuristicLab Hive Administrator",
-        MessageBoxButtons.YesNo,
-        MessageBoxIcon.Question);
-
-      if (result == DialogResult.Yes) {
-        if (resource is Slave) {
-          Content.Remove(resource);
-          HiveAdminClient.Delete(resource);
-        } else if (resource is SlaveGroup) {
-          if (Content.Any(x => x.ParentResourceId == resource.Id)) {
-            MessageBox.Show(
-              "Only empty resources can be deleted.",
-              "HeuristicLab Hive Administrator",
-              MessageBoxButtons.OK,
-              MessageBoxIcon.Error);
-          } else {
-            Content.Remove(resource);
-            HiveAdminClient.Delete(resource);
-          }
-        }
+      try {
+        HiveAdminClient.Instance.Refresh();
+        Content = HiveAdminClient.Instance.Resources;
+      } catch(AnonymousUserException) {
+        ShowHiveInformationDialog();
+      }
+    }
+
+    private void RemoveResource(Resource resource) {
+      if (resource == null || resource.Id == Guid.Empty) return;
+
+      try {
+        HiveAdminClient.Delete(resource);
+        Content.Remove(selectedResource);
+      } catch(AnonymousUserException) {
+        ShowHiveInformationDialog();
       }
     }
@@ -456,7 +572,26 @@
       return resource != null
           && resource.Name != ungroupedGroupName
-          && resource.Id != Guid.Empty
+          //&& resource.Id != Guid.Empty
           && UserInformation.Instance.UserExists
-          && (resource.OwnerUserId == UserInformation.Instance.User.Id || HiveRoles.CheckAdminUserPermissions());
+          && (HiveRoles.CheckAdminUserPermissions()
+            || HiveAdminClient.Instance.CheckOwnershipOfResource(resource, UserInformation.Instance.User.Id));
+    }
+
+    private bool IsAdmin() {
+      return HiveRoles.CheckAdminUserPermissions();
+    }
+
+    private void ChangeSelectedResourceNode(TreeNode resourceNode) {
+      selectedResource = (Resource)resourceNode.Tag;
+      ResetTreeNodes(treeView.Nodes, selectedColor, Color.Transparent, true);
+      resourceNode.BackColor = selectedColor;
+      resourceNode.Text += " [selected]";
+    }
+
+    private void SetEnabledStateOfControlsForSelectedResource() {
+      bool enabled = (IsAdmin()) ? true : false;
+      btnAddGroup.Enabled = enabled;
+      btnRemoveGroup.Enabled = enabled;
+      btnSave.Enabled = enabled;
     }
 
Index: /branches/HiveProjectManagement/HeuristicLab.Clients.Hive.Administrator/3.3/Views/ScheduleView.cs
===================================================================
--- /branches/HiveProjectManagement/HeuristicLab.Clients.Hive.Administrator/3.3/Views/ScheduleView.cs	(revision 15741)
+++ /branches/HiveProjectManagement/HeuristicLab.Clients.Hive.Administrator/3.3/Views/ScheduleView.cs	(revision 15742)
@@ -222,4 +222,10 @@
     protected override void SetEnabledStateOfControls() {
       base.SetEnabledStateOfControls();
+      bool enabled = Content != null && !Locked;
+      btCreate.Enabled = enabled;
+      btbDelete.Enabled = enabled;
+      btnClearCal.Enabled = enabled;
+      btnRecurrence.Enabled = enabled;
+      btnSaveCal.Enabled = enabled;
     }
 
Index: /branches/HiveProjectManagement/HeuristicLab.Clients.Hive/3.3/HiveAdminClient.cs
===================================================================
--- /branches/HiveProjectManagement/HeuristicLab.Clients.Hive/3.3/HiveAdminClient.cs	(revision 15741)
+++ /branches/HiveProjectManagement/HeuristicLab.Clients.Hive/3.3/HiveAdminClient.cs	(revision 15742)
@@ -25,4 +25,5 @@
 using HeuristicLab.Core;
 using System.Collections.Generic;
+using System.Linq;
 
 namespace HeuristicLab.Clients.Hive {
@@ -64,4 +65,25 @@
     }
 
+    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; }
+    }
+
+
     #endregion
 
@@ -89,4 +111,9 @@
         projects = new ItemList<Project>();
 
+        projectAncestors = new Dictionary<Guid, HashSet<Project>>();
+        projectDescendants = new Dictionary<Guid, HashSet<Project>>();
+        resourceAncestors = new Dictionary<Guid, HashSet<Resource>>();
+        resourceDescendants = new Dictionary<Guid, HashSet<Resource>>();
+
         HiveServiceLocator.Instance.CallHiveService(service => {
           service.GetSlaveGroupsForAdministration().ForEach(g => resources.Add(g));
@@ -94,4 +121,7 @@
           service.GetProjectsForAdministration().ForEach(p => projects.Add(p));
         });
+
+        UpdateResourceGenealogy();
+        UpdateProjectGenealogy();
       }
       catch {
@@ -100,4 +130,52 @@
       finally {
         OnRefreshed();
+      }
+    }
+
+    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;
+          }
+        }
+      }
+    }
+
+    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;
+          }
+        }
       }
     }
@@ -179,5 +257,5 @@
     }
 
-    #region
+    #region Helper
     public bool CheckAccessToAdminAreaGranted() {
       if(projects != null) {
@@ -191,4 +269,38 @@
       }
     }
+
+    public bool CheckOwnershipOfResource(Resource res, Guid userId) {
+      if (res == null || userId == Guid.Empty) return false;
+
+      if (res.OwnerUserId == userId) {
+        return true;
+      } else if(resourceAncestors.ContainsKey(res.Id)) {
+        return resourceAncestors[res.Id].Where(x => x.OwnerUserId == userId).Any();
+      }
+
+      return false;
+    }
+
+    public bool CheckOwnershipOfProject(Project pro, Guid userId) {
+      if (pro == null || userId == Guid.Empty) return false;
+
+      if (pro.OwnerUserId == userId) {
+        return true;
+      } else if (projectAncestors.ContainsKey(pro.Id)) {
+        return projectAncestors[pro.Id].Where(x => x.OwnerUserId == userId).Any();
+      }
+
+      return false;
+    }
+
+    public bool CheckOwnershipOfParentProject(Project pro, Guid userId) {
+      if (pro == null || userId == Guid.Empty) return false;
+
+      if(projectAncestors.ContainsKey(pro.Id)) {
+        return projectAncestors[pro.Id].Where(x => x.OwnerUserId == userId).Any();
+      }
+
+      return false;
+    }
     #endregion
   }
Index: /branches/HiveProjectManagement/HeuristicLab.Clients.Hive/3.3/HiveClient.cs
===================================================================
--- /branches/HiveProjectManagement/HeuristicLab.Clients.Hive/3.3/HiveClient.cs	(revision 15741)
+++ /branches/HiveProjectManagement/HeuristicLab.Clients.Hive/3.3/HiveClient.cs	(revision 15742)
@@ -169,5 +169,5 @@
       if (item.Id == Guid.Empty) {
         if (item is RefreshableJob) {
-          HiveClient.Instance.UploadJob((RefreshableJob)item, cancellationToken);
+          item.Id = HiveClient.Instance.UploadJob((RefreshableJob)item, cancellationToken);
         }
         if (item is JobPermission) {
@@ -180,5 +180,5 @@
         }
         if (item is Project) {
-          HiveServiceLocator.Instance.CallHiveService(s => s.AddProject((Project)item));
+          item.Id = HiveServiceLocator.Instance.CallHiveService(s => s.AddProject((Project)item));
         }
       } else {
@@ -302,5 +302,5 @@
     private static object jobCountLocker = new object();
     private static object pluginLocker = new object();
-    private void UploadJob(RefreshableJob refreshableJob, CancellationToken cancellationToken) {
+    private Guid UploadJob(RefreshableJob refreshableJob, CancellationToken cancellationToken) {
       try {
         refreshableJob.IsProgressing = true;
@@ -347,4 +347,5 @@
         refreshableJob.Progress.Finish();
       }
+      return (refreshableJob.Job != null) ? refreshableJob.Job.Id : Guid.Empty;
     }
 
