Index: /branches/2839_HiveProjectManagement/HeuristicLab.Clients.Access.Views/3.3/UserViews/RefreshableLightweightUserInformationView.Designer.cs
===================================================================
--- /branches/2839_HiveProjectManagement/HeuristicLab.Clients.Access.Views/3.3/UserViews/RefreshableLightweightUserInformationView.Designer.cs	(revision 15954)
+++ /branches/2839_HiveProjectManagement/HeuristicLab.Clients.Access.Views/3.3/UserViews/RefreshableLightweightUserInformationView.Designer.cs	(revision 15954)
@@ -0,0 +1,97 @@
+﻿#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2018 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ *
+ * This file is part of HeuristicLab.
+ *
+ * HeuristicLab is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * HeuristicLab is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
+ */
+#endregion
+
+namespace HeuristicLab.Clients.Access.Views {
+  partial class RefreshableLightweightUserInformationView {
+    /// <summary> 
+    /// Required designer variable.
+    /// </summary>
+    private System.ComponentModel.IContainer components = null;
+
+    /// <summary> 
+    /// Clean up any resources being used.
+    /// </summary>
+    /// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
+    protected override void Dispose(bool disposing) {
+      if (disposing && (components != null)) {
+        components.Dispose();
+      }
+      base.Dispose(disposing);
+    }
+
+    #region Component Designer generated code
+
+    /// <summary> 
+    /// Required method for Designer support - do not modify 
+    /// the contents of this method with the code editor.
+    /// </summary>
+    private void InitializeComponent() {
+      components = new System.ComponentModel.Container();
+      //this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
+      System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(typeof(RefreshableLightweightUserInformationView));
+      this.lightweightUserInformationView = new HeuristicLab.Clients.Access.Views.LightweightUserInformationView();
+      this.refreshButton = new System.Windows.Forms.Button();
+      this.toolTip = new System.Windows.Forms.ToolTip(this.components);
+      this.SuspendLayout();
+      // 
+      // refreshButton
+      // 
+      this.refreshButton.Image = HeuristicLab.Common.Resources.VSImageLibrary.Refresh;
+      this.refreshButton.Location = new System.Drawing.Point(4, 3);
+      this.refreshButton.Name = "refreshButton";
+      this.refreshButton.Size = new System.Drawing.Size(24, 24);
+      this.refreshButton.TabIndex = 1;
+      this.toolTip.SetToolTip(this.refreshButton, "Refresh data");
+      this.refreshButton.UseVisualStyleBackColor = true;
+      this.refreshButton.Click += new System.EventHandler(this.refreshButton_Click);
+      // 
+      // lightweightUserInformationView
+      // 
+      this.lightweightUserInformationView.Anchor = ((System.Windows.Forms.AnchorStyles)((((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom)
+                  | System.Windows.Forms.AnchorStyles.Left)
+                  | System.Windows.Forms.AnchorStyles.Right)));
+      this.lightweightUserInformationView.Caption = "RefreshableLightweightUserInformation View";
+      this.lightweightUserInformationView.Content = null;
+      this.lightweightUserInformationView.Location = new System.Drawing.Point(3, 33);
+      this.lightweightUserInformationView.Name = "lightweightUserInformationView";
+      this.lightweightUserInformationView.ReadOnly = false;
+      this.lightweightUserInformationView.Size = new System.Drawing.Size(378, 245);
+      this.lightweightUserInformationView.TabIndex = 2;
+      // 
+      // RefreshableLightweightUserInformationView
+      // 
+      this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
+      this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
+      this.Controls.Add(lightweightUserInformationView);
+      this.Controls.Add(this.refreshButton);
+      this.Name = "RefreshableLightweightUserInformationView";
+      this.Size = new System.Drawing.Size(384, 281);
+      this.Controls.SetChildIndex(this.refreshButton, 0);
+      this.ResumeLayout(false);
+    }
+
+    #endregion
+
+    private LightweightUserInformationView lightweightUserInformationView;
+    private System.Windows.Forms.ToolTip toolTip;
+    private System.Windows.Forms.Button refreshButton;
+  }
+}
Index: /branches/2839_HiveProjectManagement/HeuristicLab.Clients.Access.Views/3.3/UserViews/RefreshableLightweightUserInformationView.cs
===================================================================
--- /branches/2839_HiveProjectManagement/HeuristicLab.Clients.Access.Views/3.3/UserViews/RefreshableLightweightUserInformationView.cs	(revision 15954)
+++ /branches/2839_HiveProjectManagement/HeuristicLab.Clients.Access.Views/3.3/UserViews/RefreshableLightweightUserInformationView.cs	(revision 15954)
@@ -0,0 +1,144 @@
+﻿#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2018 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ *
+ * This file is part of HeuristicLab.
+ *
+ * HeuristicLab is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * HeuristicLab is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
+ */
+#endregion
+
+using System;
+using System.Windows.Forms;
+using HeuristicLab.MainForm;
+using HeuristicLab.MainForm.WindowsForms;
+
+namespace HeuristicLab.Clients.Access.Views {
+  [View("RefreshableLightweightUserInformation View")]
+  [Content(typeof(LightweightUser), false)]
+  public partial class RefreshableLightweightUserInformationView : AsynchronousContentView {
+    public new LightweightUser Content {
+      get { return (LightweightUser)base.Content; }
+      set { base.Content = value; }
+    }
+
+    public RefreshableLightweightUserInformationView() {
+      InitializeComponent();
+      //lightweightUserInformationView.Content = UserInformation.Instance.User;
+    }
+
+    protected override void OnContentChanged() {
+      base.OnContentChanged();
+      lightweightUserInformationView.Content = Content;
+    }
+
+    protected override void SetEnabledStateOfControls() {
+      base.SetEnabledStateOfControls();
+      refreshButton.Enabled = Content != null;
+    }
+
+    protected override void DeregisterContentEvents() {
+      Refreshing -= new EventHandler(Content_Refreshing);
+      Refreshed -= new EventHandler(Content_Refreshed);
+      base.DeregisterContentEvents();
+    }
+
+    protected override void RegisterContentEvents() {
+      base.RegisterContentEvents();
+      Refreshing += new EventHandler(Content_Refreshing);
+      Refreshed += new EventHandler(Content_Refreshed);
+    }
+
+    protected void Content_Refreshing(object sender, EventArgs e) {
+      if (InvokeRequired) {
+        Invoke(new EventHandler(Content_Refreshing), sender, e);
+      } else {
+        Cursor = Cursors.AppStarting;
+        refreshButton.Enabled = false;
+
+        lightweightUserInformationView.Enabled = false;
+      }
+    }
+
+    protected void Content_Refreshed(object sender, EventArgs e) {
+      if (InvokeRequired) {
+        Invoke(new EventHandler(Content_Refreshed), sender, e);
+      } else {
+        Cursor = Cursors.Default;
+        refreshButton.Enabled = true;
+
+        lightweightUserInformationView.Enabled = true;
+        if (!UserInformation.Instance.UserExists) {
+          MessageBox.Show("Couldn't fetch user information from the server." + Environment.NewLine +
+            "Please verify that you have an existing user and that your user name and password is correct. ", "HeuristicLab Access Service", MessageBoxButtons.OK, MessageBoxIcon.Error);
+          lightweightUserInformationView.Content = null;
+        } else {
+          lightweightUserInformationView.Content = Content;
+        }
+      }
+    }
+
+    void lightweightUserInformationView_Changed(object sender, EventArgs e) {
+      //if (!storeButton.Enabled) storeButton.Enabled = true;
+    }
+
+    private void RefreshUserData() {
+      UserInformation.Instance.Refresh();
+      lightweightUserInformationView.UserInformationChanged += new EventHandler(lightweightUserInformationView_Changed);
+    }
+
+    private void RefreshData() {
+      ExecuteActionAsync(RefreshUserData, PluginInfrastructure.ErrorHandling.ShowErrorDialog);
+    }
+
+    public void ManualRefresh() {
+      RefreshData();
+    }
+
+    protected void refreshButton_Click(object sender, System.EventArgs e) {
+      RefreshData();
+    }
+
+    public void ExecuteActionAsync(Action action, Action<Exception> exceptionCallback) {
+      var call = new Func<Exception>(delegate () {
+        try {
+          OnRefreshing();
+          action();
+        } catch (Exception ex) {
+          return ex;
+        } finally {
+          OnRefreshed();
+        }
+        return null;
+      });
+      call.BeginInvoke(delegate (IAsyncResult result) {
+        Exception ex = call.EndInvoke(result);
+        if (ex != null) exceptionCallback(ex);
+      }, null);
+    }
+
+    #region Events
+    public event EventHandler Refreshing;
+    private void OnRefreshing() {
+      EventHandler handler = Refreshing;
+      if (handler != null) handler(this, EventArgs.Empty);
+    }
+    public event EventHandler Refreshed;
+    private void OnRefreshed() {
+      EventHandler handler = Refreshed;
+      if (handler != null) handler(this, EventArgs.Empty);
+    }
+    #endregion
+  }
+}
Index: /branches/2839_HiveProjectManagement/HeuristicLab.Clients.Hive.Administrator/3.3/Views/ProjectPermissionsView.cs
===================================================================
--- /branches/2839_HiveProjectManagement/HeuristicLab.Clients.Hive.Administrator/3.3/Views/ProjectPermissionsView.cs	(revision 15953)
+++ /branches/2839_HiveProjectManagement/HeuristicLab.Clients.Hive.Administrator/3.3/Views/ProjectPermissionsView.cs	(revision 15954)
@@ -123,5 +123,9 @@
     private void treeView_BeforeCheck(object sender, TreeViewCancelEventArgs e) {
       var checkedPermission = (UserGroupBase)e.Node.Tag;
-      if (e.Node.Parent == null || newInheritedPermissions.Contains(checkedPermission) || checkedPermission.Id == Guid.Empty) e.Cancel = true;
+      if (e.Node.Parent == null 
+        || newInheritedPermissions.Contains(checkedPermission) 
+        || checkedPermission.Id == Guid.Empty
+        || Content.OwnerUserId == checkedPermission.Id)
+          e.Cancel = true;
     }
 
Index: /branches/2839_HiveProjectManagement/HeuristicLab.Services.Hive/3.3/HiveService.cs
===================================================================
--- /branches/2839_HiveProjectManagement/HeuristicLab.Services.Hive/3.3/HiveService.cs	(revision 15953)
+++ /branches/2839_HiveProjectManagement/HeuristicLab.Services.Hive/3.3/HiveService.cs	(revision 15954)
@@ -675,5 +675,5 @@
     #region Project Methods
     public Guid AddProject(DT.Project projectDto) {
-      if (projectDto == null) return Guid.Empty;
+      if (projectDto == null || projectDto.Id != Guid.Empty) return Guid.Empty;
       RoleVerifier.AuthenticateForAnyRole(HiveRoles.Administrator, HiveRoles.Client);
       // check if current (non-admin) user is owner of one of projectDto's-parents
@@ -689,6 +689,13 @@
       using (new PerformanceLogger("AddProject")) {
         var projectDao = pm.ProjectDao;
+
         return pm.UseTransaction(() => {
           var project = projectDao.Save(projectDto.ToEntity());
+          project.ProjectPermissions.Clear();
+          project.ProjectPermissions.Add(new DA.ProjectPermission {
+            GrantedUserId = project.OwnerUserId,
+            GrantedByUserId = UserManager.CurrentUserId
+          });
+
           pm.SubmitChanges();
           return project.ProjectId;
@@ -707,10 +714,47 @@
       using (new PerformanceLogger("UpdateProject")) {
         var projectDao = pm.ProjectDao;
+        var assignedJobResourceDao = pm.AssignedJobResourceDao;
         pm.UseTransaction(() => {
           var project = projectDao.GetById(projectDto.Id);
-          if (project != null) {
+          if (project != null) { // update existent
+            var formerOwnerId = project.OwnerUserId;
             projectDto.CopyToEntity(project);
-          } else {
-            projectDao.Save(projectDto.ToEntity());
+
+            // if owner has changed...
+            if(formerOwnerId != projectDto.OwnerUserId) {
+              var formerPermissionItem = project.ProjectPermissions.Where(x => x.GrantedUserId == formerOwnerId).FirstOrDefault();
+              if (formerPermissionItem != null) {
+                // remove permissions
+                project.ProjectPermissions.Remove(formerPermissionItem);
+                // remove jobs if former owner is no member of a still permitted group
+                var ugt = GetUserGroupTree();
+                var permittedGuids = new HashSet<Guid>(); // User- and Group-Guids
+                // get all member-Guids of all still permitted groups
+                foreach (var item in project.ProjectPermissions) {
+                  permittedGuids.Add(item.GrantedUserId);
+                  if(ugt.ContainsKey(item.GrantedUserId)) {
+                    ugt[item.GrantedUserId].ToList().ForEach(x => permittedGuids.Add(x));
+                  }
+
+                  // check if former owner Guid is in Member-Guids
+                  // if yes: do nothing, if not do: 
+                  if (!permittedGuids.Contains(formerOwnerId)) {
+                    assignedJobResourceDao.DeleteByProjectIdAndUserIds(project.ProjectId, new List<Guid> { formerOwnerId });
+                  }
+                }
+              }
+              project.ProjectPermissions.Add(new DA.ProjectPermission {
+                GrantedUserId = projectDto.OwnerUserId,
+                GrantedByUserId = UserManager.CurrentUserId
+              });
+            }
+
+          } else { // save new
+            var newProject = projectDao.Save(projectDto.ToEntity());
+            newProject.ProjectPermissions.Clear();
+            newProject.ProjectPermissions.Add(new DA.ProjectPermission {
+              GrantedUserId = projectDto.OwnerUserId,
+              GrantedByUserId = UserManager.CurrentUserId
+            });
           }
           pm.SubmitChanges();
@@ -841,6 +885,35 @@
             project.ProjectPermissions.Clear();
           } else {
-            assignedJobResourceDao.DeleteByProjectIdAndUserIds(project.ProjectId, removedPermissions);
-            foreach(var item in project.ProjectPermissions
+
+            var ugt = GetUserGroupTree();
+            var permittedGuids = new HashSet<Guid>(); // User- and Group-Guids
+            var notpermittedGuids = new HashSet<Guid>();
+
+            // remove job assignments:
+            // (1) get all member-Guids of all still or fresh permitted user/groups
+            foreach (var item in grantedUserIds) {
+              permittedGuids.Add(item);
+              if (ugt.ContainsKey(item)) {
+                ugt[item].ToList().ForEach(x => permittedGuids.Add(x));
+              }
+            }
+
+            // (2) get all member-Guids of users and groups in removedPermissions
+            foreach (var item in removedPermissions) {
+              notpermittedGuids.Add(item);
+              if (ugt.ContainsKey(item)) {
+                ugt[item].ToList().ForEach(x => notpermittedGuids.Add(x));
+              }
+            }
+
+            // (3) get all Guids which are in removedPermissions but not in grantedUserIds
+            var definatelyNotPermittedGuids = notpermittedGuids.Except(permittedGuids);
+
+            // (4) delete jobs of those
+            assignedJobResourceDao.DeleteByProjectIdAndUserIds(project.ProjectId, definatelyNotPermittedGuids);
+
+
+            // remove project permissions
+            foreach (var item in project.ProjectPermissions
               .Where(x => removedPermissions.Contains(x.GrantedUserId))
               .ToList()) {
