Index: /branches/WebJobManager/HeuristicLab.Clients.Hive.WebJobManager/Controllers/HomeController.cs
===================================================================
--- /branches/WebJobManager/HeuristicLab.Clients.Hive.WebJobManager/Controllers/HomeController.cs	(revision 13804)
+++ /branches/WebJobManager/HeuristicLab.Clients.Hive.WebJobManager/Controllers/HomeController.cs	(revision 13805)
@@ -93,4 +93,8 @@
             }
         }
+        /// <summary>
+        /// Redirect user to home sceen for a full logout
+        /// </summary>
+        /// <returns></returns>
         public IActionResult Logout()
         {
Index: /branches/WebJobManager/HeuristicLab.Clients.Hive.WebJobManager/Controllers/ResourceController.cs
===================================================================
--- /branches/WebJobManager/HeuristicLab.Clients.Hive.WebJobManager/Controllers/ResourceController.cs	(revision 13804)
+++ /branches/WebJobManager/HeuristicLab.Clients.Hive.WebJobManager/Controllers/ResourceController.cs	(revision 13805)
@@ -14,4 +14,7 @@
 namespace HeuristicLab.Clients.Hive.WebJobManager.Controllers
 {
+    /// <summary>
+    /// Controller for the resources. Only handles requests that refresh the page.
+    /// </summary>
     public class ResourceController : Controller
     {
@@ -29,4 +32,8 @@
             _environment = env;
         }
+        /// <summary>
+        /// Initialize and check the login. Gets all the required services for the user.  
+        /// </summary>
+        /// <returns></returns>
         private bool init()
         {
@@ -46,4 +53,8 @@
             }
         }
+        /// <summary>
+        /// Loads the main page for the resources
+        /// </summary>
+        /// <returns></returns>
         public IActionResult Index()
         {
@@ -60,4 +71,10 @@
             }
         }
+        /// <summary>
+        /// Changes the parent for a specfic resource
+        /// </summary>
+        /// <param name="inpid">Resource to edit</param>
+        /// <param name="inpidpar">New parent resource</param>
+        /// <returns></returns>
         [HttpPost]
         public IActionResult changeParent(string inpid, string inpidpar)
@@ -70,17 +87,22 @@
                 adminClient.Refresh();
                 var tochange = adminClient.Resources.ToList().Find(x => x.Id == gid);
-                
+                //gets current resource
                 if (inpidpar != null && inpidpar != "") {
                     Guid tempid = Guid.Parse(inpidpar);
-                    while (tempid != null)
-                    {
+                    while (tempid != null && tempid != Guid.Empty)
+                    {//Check if a loop could occur (some parent of the parent being the parent)
                         if (tempid != gid)
-                        {
-                            tempid = (Guid)adminClient.Resources.ToList().Find(x => x.Id == tempid).ParentResourceId;
+                        {//Not equal so move up a level
+                            var t = adminClient.Resources.ToList().Find(x => x.Id == tempid);
+                            if (t.ParentResourceId == null)
+                                tempid = Guid.Empty;
+                            else
+                                tempid = (Guid)t.ParentResourceId;
+
                         }
                         else
-                            break;
-                    }
-                    if(tempid == null)
+                            break; //breaks loop if equal 
+                    }
+                    if(tempid == null || tempid == Guid.Empty)//Broken loop => the tempid is not empty so no change
                         tochange.ParentResourceId = Guid.Parse(inpidpar);
                 }
@@ -88,12 +110,66 @@
                     tochange.ParentResourceId = null;
                 adminClient.Store(tochange, CancellationToken.None);
-
-                return RedirectToAction("Index", "Resource");
-            }
-            else
-            {
-                return RedirectToAction("Index", "Home");
-            }
-        }
+                //Save to server
+
+                return RedirectToAction("Index", "Resource");
+            }
+            else
+            {
+                return RedirectToAction("Index", "Home");
+            }
+        }
+        /// <summary>
+        /// Adds recources to a resource group
+        /// </summary>
+        /// <param name="addres">Array containing all the resources ID's from the group</param>
+        /// <param name="groupid">Group id</param>
+        /// <returns></returns>
+        [HttpPost]
+        public IActionResult addResourcesToGroup(string[] addres, string groupid)
+        {
+            if (init())
+            {
+                Guid gid = Guid.Parse(groupid);
+                adminClient.Refresh();
+                var exist = adminClient.Resources.ToList().FindAll(x => x.ParentResourceId == gid);
+                //Current existing member of the group
+
+                foreach(var a in addres)
+                {//loop on each ID 
+                    Guid tempid = Guid.Parse(a);
+                    var elemid = exist.FindIndex(x => x.Id == tempid);
+                    if (elemid != -1)
+                    {//If element already is a member of the group: scramble temporary ID (for future reference) 
+                        exist[elemid].Id = Guid.Empty;
+                    }
+                    else
+                    {//If element is not yet in list => change parentresourceid from that element
+                        var obj = adminClient.Resources.ToList().Find(x => x.Id == tempid);
+                        obj.ParentResourceId = gid;
+                        adminClient.Store(obj, CancellationToken.None);
+                    }
+                }
+                foreach(var e in exist)
+                {//Loop on existing and check the ID's
+                    if(e.Id != Guid.Empty)
+                    {//ID != Empty means that element should not be a member of the list anymore
+                        e.ParentResourceId = null; //remove ParentResourceID from element
+                        adminClient.Store(e, CancellationToken.None);
+                    }
+                }
+
+                return RedirectToAction("Index", "Resource");
+
+            }
+            else
+            {
+                return RedirectToAction("Index", "Home");
+            }
+        }
+        /// <summary>
+        /// Delete a client group (relinks the parent from every member to possible grandparent) 
+        /// </summary>
+        /// <param name="inpid">Group ID to delete</param>
+        /// <returns></returns>
         [HttpPost]
         public IActionResult deleteClientGroup(string inpid)
@@ -105,7 +181,9 @@
                 adminClient.Refresh();
                 var group = adminClient.Resources.ToList().Find(x => x.Id == gid);
+                //Group to delete
                 var list = adminClient.Resources.ToList().FindAll(x => x.ParentResourceId == gid);
+                //All members from the group
                 foreach(var cl in list)
-                {
+                {//Links parent from every child to parent from the group to delete.
                     cl.ParentResourceId = group.ParentResourceId;
                     adminClient.Store(cl, CancellationToken.None);
@@ -120,5 +198,12 @@
             }
         }
-
+        /// <summary>
+        /// Create a new Client Group
+        /// </summary>
+        /// <param name="inpname">Name for the group</param>
+        /// <param name="inpheart">Heartbeat</param>
+        /// <param name="inpparent">Possible parent for the group</param>
+        /// <param name="clientstoadd">Clients to be added to the group</param>
+        /// <returns></returns>
         [HttpPost]
         public IActionResult newClientGroup(string inpname, int inpheart, string inpparent, string[] clientstoadd)
@@ -128,15 +213,18 @@
 
                 SlaveGroup sg = new SlaveGroup();
+                //init
                 sg.Id = Guid.Empty;
                 sg.Name = inpname;
                 sg.HbInterval = inpheart;
-                if (inpparent != "")
+                if (inpparent != null)
                     sg.ParentResourceId = Guid.Parse(inpparent);
+
                 sg.OwnerUserId = serviceLocator.getHiveServiceClient().GetUserIdByUsername(serviceLocator.getHiveServiceClient().ClientCredentials.UserName.UserName);
                 adminClient.Store(sg, CancellationToken.None);
                 adminClient.Refresh();
+                //Reloads the resources
                 var id = adminClient.Resources.ToList().Find(x => x.Name == inpname).Id;
                 foreach(var s in clientstoadd)
-                {
+                {//Loop so each client can be added to the group
                     var cid = Guid.Parse(s);
                     var client = adminClient.Resources.ToList().Find(x => x.Id == cid);
Index: /branches/WebJobManager/HeuristicLab.Clients.Hive.WebJobManager/Controllers/UserController.cs
===================================================================
--- /branches/WebJobManager/HeuristicLab.Clients.Hive.WebJobManager/Controllers/UserController.cs	(revision 13804)
+++ /branches/WebJobManager/HeuristicLab.Clients.Hive.WebJobManager/Controllers/UserController.cs	(revision 13805)
@@ -8,4 +8,5 @@
 using System.Collections.Generic;
 using System.Linq;
+using System.Net.Mail;
 using System.ServiceModel.Security;
 using System.Threading.Tasks;
@@ -13,4 +14,7 @@
 namespace HeuristicLab.Clients.Hive.WebJobManager.Controllers
 {
+    /// <summary>
+    /// Handles all the actions for user management
+    /// </summary>
     public class UserController : Controller
     {
@@ -27,4 +31,8 @@
             _environment = env;
         }
+        /// <summary>
+        /// Init required services and checks login
+        /// </summary>
+        /// <returns></returns>
         private bool init()
         {
@@ -44,5 +52,8 @@
         }
         #region Users
-
+        /// <summary>
+        /// Show users page
+        /// </summary>
+        /// <returns></returns>
         public IActionResult Index()
         {
@@ -51,4 +62,5 @@
                 ViewBag.Title = "Users";
                 UserViewModel vm = new UserViewModel(accessClient).refreshAll() ;
+                //Refreshall for users, groups and roles 
                 ViewBag.SessionId = HttpContext.Session.GetString("UserId");
                 return View("Index", vm);
@@ -62,5 +74,4 @@
         public IActionResult SelectUser(string id)
         {
-            ;
             if (init())
             {
@@ -69,9 +80,9 @@
                 UserViewModel vm = new UserViewModel(accessClient).refreshAll();
                 if (curr == Guid.Empty)
-                {
+                {//new user
                     ViewBag.Title = "Add User";
                 }
                 else
-                {
+                {//View an existing user
                     vm.SelectedUser = vm.getUserById(curr);
                     vm.SelectedUserSubscriptions = accessClient.getSubscribedGroups(curr);
@@ -82,10 +93,21 @@
                 ViewBag.SessionId = HttpContext.Session.GetString("UserId");
                 return View("Index", vm);
-            }
-            else
-            {
-                return RedirectToAction("Index", "Home");
-            }
-        }
+                //Uses Index page too, with the additional info in the Viewmodel
+            }
+            else
+            {
+                return RedirectToAction("Index", "Home");
+            }
+        }
+        /// <summary>
+        /// Saves an existing user or adds a new user
+        /// </summary>
+        /// <param name="inpusername">Username</param>
+        /// <param name="inpfullname">Full name </param>
+        /// <param name="inpemail">Email</param>
+        /// <param name="u">User ID</param>
+        /// <param name="rolestoadd">Roles to add to the user</param>
+        /// <param name="groupstoadd">Groups to subscribe the user to</param>
+        /// <returns></returns>
         [HttpPost]
         public IActionResult saveUser(string inpusername, string inpfullname, string inpemail, string u, string[] rolestoadd, string[] groupstoadd)
@@ -96,5 +118,5 @@
                 var uid = Guid.Parse(u);
                 Access.User user;
-                if (uid == Guid.Empty)
+                if (uid == Guid.Empty)//checks if user is new or exists
                     user = new Access.User();
                 else
@@ -107,18 +129,21 @@
 
                 if (uid == Guid.Empty)
-                {
+                {//New user
                     user.UserName = inpusername;
                     uid = accessClient.addUser(user);
+                    var newpass = accessClient.resetPassword(uid);
+                    sendPassmail(accessClient.Users.Find(x => x.Id == uid), newpass);
+                    //password received through mail
                     ViewBag.Title = user.UserName + " added - User";
                 }
                 else
-                {
+                {//Existing user
                     accessClient.updateUser(user);
                     ViewBag.Title = user.UserName + " updated - User";
                 }
-                accessClient.RefreshUsers();
+                accessClient.RefreshUsers();//Refresh data from user
                 user = accessClient.Users.Find(x => x.Id == uid);
                 foreach (var s in rolestoadd)
-                {
+                {//Loop to add roles
                     var role = accessClient.Roles.Find(x => x.Name == s);
 
@@ -127,5 +152,5 @@
                 accessClient.RefreshUserGroups();
                 foreach(var g in groupstoadd)
-                {
+                {//loop to subscribe to groups
                     var gid = Guid.Parse(g);
                     var group = accessClient.Groups.Find(x => x.Id == gid);
@@ -140,4 +165,35 @@
 
         }
+        /// <summary>
+        /// Sends email for a specific user, containg a password
+        /// </summary>
+        /// <param name="u">User to mail</param>
+        /// <param name="pass">Password to send</param>
+        public static void sendPassmail(Access.User u, string pass)
+        {/*
+            SmtpClient smtpClient = new SmtpClient("mail.MyWebsiteDomainName.com", 25);
+
+            smtpClient.Credentials = new System.Net.NetworkCredential("info@MyWebsiteDomainName.com", "myIDPassword");
+            smtpClient.UseDefaultCredentials = true;
+            smtpClient.DeliveryMethod = SmtpDeliveryMethod.Network;
+            smtpClient.EnableSsl = true;
+            MailMessage mail = new MailMessage();
+
+            //Setting From , To and CC
+            mail.From = new MailAddress("info@MyWebsiteDomainName", "MyWeb Site");
+            mail.Subject = "Password changed - HeuristicLab Hive";
+            mail.Body = "Hello " + u.FullName + ", " +
+                "Your password was changed through the HeuristicLab Hive web application." +
+                "The new password for " + u.UserName + " is '" + pass + "'.";
+            mail.To.Add(new MailAddress(u.Email));
+
+            smtpClient.Send(mail);
+            */
+        }
+        /// <summary>
+        /// Delete a user
+        /// </summary>
+        /// <param name="id">User ID to delete</param>
+        /// <returns></returns>
         public IActionResult deleteUser(string id)
         {
@@ -148,5 +204,5 @@
 
                 if (uid == Guid.Empty)
-                {
+                {//check for empty Guid, should not happen but still
                     vm.message = "Something went wrong, user is not deleted";
                     return View("Index", vm);
@@ -157,16 +213,21 @@
                     vm.message = user.UserName + " (" + user.FullName + ") has been deleted";
                     accessClient.DeleteUser(user);
-                    vm.refreshAll();
+                    vm.refreshAll();//refreshAll for index view
                     ViewBag.Title = "Users";
-                    return View("Index", vm);
-                }
-            }
-            else
-            {
-                return RedirectToAction("Index", "Home");
-            }
-
-        }
-
+                    return View("Index", vm);//No redirect to save the viewbag message
+                }
+            }
+            else
+            {
+                return RedirectToAction("Index", "Home");
+            }
+
+        }
+        /// <summary>
+        /// Deletes a role from a user
+        /// </summary>
+        /// <param name="id">User Id</param>
+        /// <param name="role">Role name</param>
+        /// <returns></returns>
         public IActionResult deleteUserRole(string id, string role)
         {
@@ -178,4 +239,5 @@
                 var user = vm.getUserById(uid);
                 var r = vm.getRoleByName(role);
+
                 accessClient.deleteUserRole(user, r);
                 return RedirectToAction("SelectUser", new { id = id });
@@ -186,4 +248,10 @@
             }
         }
+        /// <summary>
+        /// Delete user from a group
+        /// </summary>
+        /// <param name="id">User Id</param>
+        /// <param name="group">Group Id</param>
+        /// <returns></returns>
         public IActionResult deleteUserGroup(string id, string group)
         {
@@ -196,4 +264,5 @@
                 var user = vm.getUserById(mid);
                 var gr = vm.getGroupById(gid);
+                
                 accessClient.deleteMember(user, gr);
                 return RedirectToAction("SelectUser", new { id = id});
@@ -208,4 +277,8 @@
 
         #region Groups
+        /// <summary>
+        /// Shows the groups overview, opening up with "Add group"
+        /// </summary>
+        /// <returns></returns>
         public IActionResult Groups()
         {
@@ -222,4 +295,9 @@
             }
         }
+        /// <summary>
+        /// Show information for a specific group (Guid.empty = new group)
+        /// </summary>
+        /// <param name="id">Group ID</param>
+        /// <returns></returns>
         public IActionResult SelectGroup(string id)
         {
@@ -232,9 +310,9 @@
                     .refreshUsers();
                 if (curr == Guid.Empty)
-                {
+                {//Add group
                     ViewBag.Title = "Add group";
                 }
                 else
-                {
+                {//Show existing group info and possibility to edit
                     vm.SelectedGroup = vm.getGroupById(curr);
                     vm.SelectedGroupMembers = accessClient.getGroupMembers(curr);
@@ -249,4 +327,12 @@
             }
         }
+        /// <summary>
+        /// Saves an exisiting group or adds a new one.
+        /// </summary>
+        /// <param name="inpgroupname">Group name</param>
+        /// <param name="u">Group id (empty for new)</param>
+        /// <param name="userstoadd">Users to add to group</param>
+        /// <param name="groupstoadd">Groups to add to group</param>
+        /// <returns></returns>
         [HttpPost]
         public IActionResult saveGroup(string inpgroupname, string u, string[] userstoadd, string[] groupstoadd)
@@ -259,18 +345,18 @@
                 Access.UserGroup group;
 
+                if (uid == Guid.Empty)//Create new group
+                    group = new Access.UserGroup();
+                else//Find existing group
+                    group = accessClient.Groups.Find(x => x.Id == uid);
+
+                group.Name = inpgroupname;
+
                 if (uid == Guid.Empty)
-                    group = new Access.UserGroup();
-                else
-                    group = accessClient.Groups.Find(x => x.Id == uid);
-
-                group.Name = inpgroupname;
-
-                if (uid == Guid.Empty)
-                {
+                {//New Group add
                     uid = accessClient.addGroup(group);
                     ViewBag.Title = group.Name + " added - Group";
                 }
                 else
-                {
+                {//Existing group update
                     accessClient.updateGroup(group);
                     ViewBag.Title = group.Name + " updated - Group";
@@ -278,6 +364,7 @@
                 vm.refreshGroups();
                 group = vm.getGroupById(uid);
+                //refresh group info
                 foreach (var s in userstoadd)
-                {
+                {//Subscribes members to group
                     var tempid = Guid.Parse(s);
                     var member = vm.getUserById(tempid);
@@ -285,5 +372,5 @@
                 }
                 foreach (var g in groupstoadd)
-                {
+                {//Subscribes groups to group
                     var tempid = Guid.Parse(g);
                     var member = vm.getGroupById(tempid);
@@ -298,4 +385,9 @@
             }
         }
+        /// <summary>
+        /// Delete an existing group
+        /// </summary>
+        /// <param name="id">Group to delete</param>
+        /// <returns></returns>
         public IActionResult deleteGroup(string id)
         {
@@ -306,10 +398,10 @@
 
                 if (uid == Guid.Empty)
-                {
+                {//Check for empty ID, should not happen but still..
                     vm.message = "Something went wrong, group is not deleted";
                     return View("Groups", vm);
                 }
                 else
-                {
+                {//Deletes the user group
                     var group = vm.getGroupById(uid);
                     vm.message = group.Name + " has been deleted";
@@ -325,4 +417,10 @@
 
         }
+        /// <summary>
+        /// Delete a member from a group  
+        /// </summary>
+        /// <param name="g">Group id</param>
+        /// <param name="m">User id</param>
+        /// <returns>Group selected</returns>
         public IActionResult deleteMember(string g, string m)
         {
@@ -334,10 +432,10 @@
 
                 if (gid == Guid.Empty || mid == Guid.Empty)
-                {
+                {//Should not be empty but still..
                     vm.message = "Something went wrong, member is not deleted";
                     return View("Groups", vm);
                 }
                 else
-                {
+                {//Deletes the member
                     var group = vm.getGroupById(gid);
                     Access.UserGroupBase member = vm.getUserById(mid);
@@ -361,4 +459,8 @@
 
         #region Roles
+        /// <summary>
+        /// Shows roles overview, opening with "Add role"
+        /// </summary>
+        /// <returns></returns>
         public IActionResult Roles()
         {
@@ -376,4 +478,9 @@
             }
         }
+        /// <summary>
+        /// Shows information for a specific role 
+        /// </summary>
+        /// <param name="name">Role name</param>
+        /// <returns></returns>
         public IActionResult SelectRole(string name)
         {
@@ -383,9 +490,9 @@
                 UserViewModel vm = new UserViewModel(accessClient).refreshRoles();
                 if (name == "" || name == null)
-                {
+                {//Add role
                     ViewBag.Title = "Add Role";
                 }
                 else
-                {
+                {//Edit/view role
                     vm.SelectedRole = vm.getRoleByName(name);
                     vm.SelectedRoleEnrolled = accessClient.getEnrolled(vm.SelectedRole);
@@ -401,4 +508,9 @@
             }
         }
+        /// <summary>
+        /// Saves a role or adds a new one
+        /// </summary>
+        /// <param name="inprolename">Role name</param>
+        /// <returns></returns>
         [HttpPost]
         public IActionResult saveRole(string inprolename)
@@ -422,4 +534,9 @@
             }
         }
+        /// <summary>
+        /// Delete a role
+        /// </summary>
+        /// <param name="name">Role name</param>
+        /// <returns></returns>
         public IActionResult deleteRole(string name)
         {
@@ -434,4 +551,10 @@
             }
         }
+        /// <summary>
+        /// Deletes a user from a role
+        /// </summary>
+        /// <param name="id">User id</param>
+        /// <param name="role">Role name</param>
+        /// <returns></returns>
         public IActionResult deleteRoleUser(string id, string role)
         {
Index: /branches/WebJobManager/HeuristicLab.Clients.Hive.WebJobManager/Hubs/CalendarHub.cs
===================================================================
--- /branches/WebJobManager/HeuristicLab.Clients.Hive.WebJobManager/Hubs/CalendarHub.cs	(revision 13804)
+++ /branches/WebJobManager/HeuristicLab.Clients.Hive.WebJobManager/Hubs/CalendarHub.cs	(revision 13805)
@@ -12,4 +12,7 @@
 namespace HeuristicLab.Clients.Hive.WebJobManager.Hubs
 {
+    /// <summary>
+    /// SignalR Hub that manages all resource management. 
+    /// </summary>
     public class CalendarHub : Hub
     {
@@ -19,4 +22,7 @@
         private HiveServiceLocatorWeb servloc;
         private AccessAdministrationClient accessClient;
+        /// <summary>
+        /// Loads up the services for the client (Instance is only created upon a call from a client)
+        /// </summary>
         private void loader()
         {
@@ -35,4 +41,7 @@
             }
         }
+        /// <summary>
+        /// Initial client request for all user, group and resource information
+        /// </summary>
         public void requestInfo()
         {
@@ -40,4 +49,5 @@
             adminClient.Refresh();
             UserViewModel vm = new UserViewModel(accessClient).refreshAll();
+
             var users = JsonConvert.SerializeObject(vm.users);
             var groups = JsonConvert.SerializeObject(vm.ugroups);
@@ -45,4 +55,8 @@
             Clients.Caller.processData(res, users, groups);
         }
+        /// <summary>
+        /// Request for the downtimes of a specific resource
+        /// </summary>
+        /// <param name="id">Resource ID</param>
         public void requestDownTime(string id)
         {
@@ -50,9 +64,16 @@
             adminClient.Refresh();
             Guid t = Guid.Parse(id);
+
+            //Loads up the downtimes for the set resource ID
             adminClient.DowntimeForResourceId = t;
             adminClient.RefreshCalendar();
+            
             var down = JsonConvert.SerializeObject(adminClient.Downtimes);
             Clients.Caller.processDowntime(id, down);
         }
+        /// <summary>
+        /// Request for permissions of a specific resource (refreshable by recall)
+        /// </summary>
+        /// <param name="id">Resource ID</param>
         public void requestPermissions(string id)
         {
@@ -63,11 +84,21 @@
         }
 
+        /// <summary>
+        /// Edit permissions for a resource
+        /// </summary>
+        /// <param name="perms">Permissions ID's</param>
+        /// <param name="idresource">Resource ID</param>
         public void changePermissions(string[] perms, string idresource)
         {
             loader();
             var res = Guid.Parse(idresource);
+
+            //Collect current permissions
             var exist = servloc.CallHiveService(x => x.GetResourcePermissions(res));
+
+            //Separate list for new and to remove permissions
             List<Guid> newPerms = new List<Guid>();
             List<Guid> revokePerms = new List<Guid>();
+
             for (var i = 0; i < perms.Length; i++)
             {
@@ -75,15 +106,16 @@
                 var elemid = exist.FindIndex(x => x.GrantedUserId == p);
                 if (elemid != -1)
-                {
+                {//If it already exists => Scramble up Guid (checked further)
                     exist[elemid].GrantedUserId = Guid.Empty;
                 }
                 else
-                {
+                {//If it's not in the list, add to new permissions
                     newPerms.Add(p);
                 }
             }
+            //Adds the new permissions to the resource
             servloc.CallHiveService(x => x.GrantResourcePermissions(res, newPerms));
             foreach (var ex in exist)
-            {
+            {//Checks for intact ID's and adds them to the revoke list
                 if(ex.GrantedUserId != Guid.Empty)
                 {
@@ -91,7 +123,13 @@
                 }
             }
+            //Revokes all permissions that were deselected by the user
             servloc.CallHiveService(x => x.RevokeResourcePermissions(res, revokePerms));
+            //Live reload the view for the resource
             requestPermissions(idresource);
         }
+        /// <summary>
+        /// Toggles the disposable setting for a resource
+        /// </summary>
+        /// <param name="id">Resource ID</param>
         public void toggleDisposable(string id)
         {
@@ -100,19 +138,36 @@
             Guid c = Guid.Parse(id);
             var obj = adminClient.Resources.ToList().Find(x => x.Id == c);
+
+            //Toggle
             ((Slave)(obj)).IsDisposable = !((Slave)(obj)).IsDisposable;
+
             adminClient.Store(obj, CancellationToken.None);
+
+            //Notify client of successful saving
             Clients.Caller.processDispose( ((Slave)(obj)).IsDisposable);
 
         }
+        /// <summary>
+        /// Saves changes to a resource calendar
+        /// </summary>
+        /// <param name="id">Resource id</param>
+        /// <param name="del">To delete downtimes</param>
+        /// <param name="add">New downtimes</param>
+        /// <param name="upd">Downtimes to update</param>
+        /// <param name="fresh">Check if refresh should be sent (Save all current graph or Save current graph)</param>
+        /// <param name="last">Check for last request (Save all)</param>
         public void saveCalendar(string id, string[] del, string[][] add, string[][] upd, bool fresh, bool last)
         {
             loader();
             var calid = Guid.Parse(id);
+            
+            //Load up calendar
             adminClient.Refresh();
             adminClient.DowntimeForResourceId = calid;
             adminClient.RefreshCalendar();
+
             var downlist = adminClient.Downtimes.ToList();
             foreach(var s in del)
-            {
+            {//Deletes downtimes
                 var gu = Guid.Parse(s);
                 var el = downlist.Find(x => x.Id == gu);
@@ -120,5 +175,6 @@
             }
             foreach (var s in add)
-            {
+            {//Adds new downtimes
+                //init
                 var obj = new Downtime();
                 obj.Id = Guid.Empty;
@@ -134,21 +190,23 @@
                     obj.AllDayEvent = false;
                 obj.ResourceId = Guid.Parse(s[4]);
+
+                //Recurrency check
                 if (s[5] == "true")
-                {
+                {//Recurrency set
                     obj.Recurring = true;
                     if (s[6] == "0")
-                    {
+                    {//new Recur
                         var dayarr = s[9].Split(',');
                         var start = (new DateTime(1970, 1, 1)).AddMilliseconds(double.Parse(s[7]));
                         var end = (new DateTime(1970, 1, 1)).AddMilliseconds(double.Parse(s[8]));
-                        loopAddDowns(start, end, dayarr, obj);    
+                        loopAddDowns(start, end, dayarr, obj);//Loop creation of recurrency. Start to end date
                     }
                     else
-                    {
+                    {//Existing recurrency (only edits current element, client handles the creation of the other events)
                         obj.RecurringId = Guid.Parse(s[6]);
                         adminClient.Store(obj, CancellationToken.None);
                     }
                 }
-                else { 
+                else { //No recurrency
                     obj.Recurring = false;
                     adminClient.Store(obj, CancellationToken.None);
@@ -158,5 +216,5 @@
             }
             foreach(var s in upd)
-            {
+            {//Update existing downtime
                  var obj = downlist.Find(x => x.Id == Guid.Parse(s[0]));
                 if (s[1] == "Unavailable")
@@ -171,12 +229,15 @@
                     obj.AllDayEvent = false;
                 if (s[5] == "true" && !obj.Recurring)
-                {
+                {//Recurrence set
                     obj.Recurring = true;
                     if (s[6] == "00000000-0000-0000-0000-000000000000")
-                    {
+                    {//Creates new recurrence
                         var dayarr = s[9].Split(',');
                         var start = (new DateTime(1970, 1, 1)).AddMilliseconds(double.Parse(s[7]));
                         var end = (new DateTime(1970, 1, 1)).AddMilliseconds(double.Parse(s[8]));
-                        //loopAddDowns(start, end, dayarr, obj);
+                        loopAddDowns(start, end, dayarr, obj);
+                        adminClient.Delete(obj);
+                        //Delete needed to prevent doubles in the creation of the recurrency
+                        //Why: event could be on not included day of the week => loop cannot find that. 
                     }
                     else
@@ -194,23 +255,33 @@
             }
             if( last)
-            {
+            {//Last element from save all => Notify client
                 Clients.Caller.savingAllDone();
             }
             else if (fresh)
-            {
+            {//Refresh for graph needed 
                 Clients.Caller.savingCurrentDone();
             }
         }
+        /// <summary>
+        /// Creates downtimes for a new recurrency
+        /// </summary>
+        /// <param name="start">Start date</param>
+        /// <param name="end">End date</param>
+        /// <param name="dayarr">Boolean day array (sun = 0,...)</param>
+        /// <param name="obj">Downtime to recur</param>
         private void loopAddDowns(DateTime start, DateTime end, string[] dayarr, Downtime obj)
         {
             var rid = Guid.NewGuid();
-            for (; start < end;)
+            while (start < end)
             {
                 if (dayarr[(int)(start.DayOfWeek)] == "true")
-                {
+                {//Check for day of the week
+                    //Set setting for the downtime to add
                     var temp = new Downtime();
-                    temp.StartDate = start.AddHours(obj.StartDate.Hour - start.Hour).AddMinutes(obj.StartDate.Minute - start.Minute);
-                    temp.EndDate = start.AddHours(obj.EndDate.Hour - start.Hour).AddMinutes(obj.EndDate.Minute - start.Minute);
-                    temp.Id = obj.Id;
+                    temp.StartDate = start.AddHours(obj.StartDate.Hour - start.Hour)
+                        .AddMinutes(obj.StartDate.Minute - start.Minute);
+                    temp.EndDate = start.AddHours(obj.EndDate.Hour - start.Hour)
+                        .AddMinutes(obj.EndDate.Minute - start.Minute);
+                    temp.Id = Guid.Empty;
                     temp.DowntimeType = obj.DowntimeType;
                     temp.AllDayEvent = obj.AllDayEvent;
Index: /branches/WebJobManager/HeuristicLab.Clients.Hive.WebJobManager/Hubs/UserInfoHub.cs
===================================================================
--- /branches/WebJobManager/HeuristicLab.Clients.Hive.WebJobManager/Hubs/UserInfoHub.cs	(revision 13804)
+++ /branches/WebJobManager/HeuristicLab.Clients.Hive.WebJobManager/Hubs/UserInfoHub.cs	(revision 13805)
@@ -1,3 +1,4 @@
 ﻿using HeuristicLab.Clients.Access.Administration;
+using HeuristicLab.Clients.Hive.WebJobManager.Controllers;
 using HeuristicLab.Clients.Hive.WebJobManager.Services;
 using HeuristicLab.Clients.Hive.WebJobManager.ViewModels.User;
@@ -10,4 +11,7 @@
 namespace HeuristicLab.Clients.Hive.WebJobManager.Hubs
 {
+    /// <summary>
+    /// Small SignalR hub to change the password from a user
+    /// </summary>
     public class UserInfoHub: Hub
     {
@@ -15,4 +19,7 @@
         private Guid userId;
         private AccessAdministrationClient aac;
+        /// <summary>
+        /// Loads required services
+        /// </summary>
         private void loader()
         {
@@ -29,5 +36,8 @@
             }
         }
-
+        /// <summary>
+        /// Request to change pass 
+        /// </summary>
+        /// <param name="user">User id</param>
         public void resetPassword(string user)
         {
@@ -36,4 +46,5 @@
             Access.User u = new UserViewModel(aac).refreshUsers().getUserById(userid);
             var pass = aac.resetPassword(userid);
+            UserController.sendPassmail(u, pass);//Send mail + show pass            
             Clients.Caller.showNewPass(pass);
         }
Index: /branches/WebJobManager/HeuristicLab.Clients.Hive.WebJobManager/Scripts/Hubs/CalendarHubber.js
===================================================================
--- /branches/WebJobManager/HeuristicLab.Clients.Hive.WebJobManager/Scripts/Hubs/CalendarHubber.js	(revision 13804)
+++ /branches/WebJobManager/HeuristicLab.Clients.Hive.WebJobManager/Scripts/Hubs/CalendarHubber.js	(revision 13805)
@@ -12,20 +12,20 @@
                var hubber = $.connection.calendarHub;
 
-               vm.alertMessage = "No alerts";
-               vm.currentcal = [];
-               $scope.permission = false;
-               vm.selectedEventId = -1;
-               vm.groups = [];
-               vm.clients = [];
+               vm.currentcal = [];//Reference to current calendar (treeview.currentNode.calendar)
+               $scope.permissionview = false;//Show permissions or not
+               $scope.resaddview = false;//Show add resources or not
+               vm.selectedEventId = -1;//Selected downtime (-1 for none)
+               vm.groups = []; //All resource groups
+               vm.clients = []; //All resources 
                vm.init = function () {
-
-                   //  $.connection.hub.logging = true;
-
 
                    var v = document.getElementById("userId").innerHTML;
                    $.connection.hub.qs = { 'userid': v };
+                   //Connection string set to identify the unique session ID for the user
                    $.connection.hub.start().done(function () {
-                       hubber.server.requestInfo();
-                   });
+                       hubber.server.requestInfo();//initial data request
+                   });
+
+                   //Process all initial data needed (heavy load)
                    hubber.client.processData = function (data, users, groups) {
                        vm.data = JSON.parse(data);
@@ -36,4 +36,6 @@
                        $scope.$apply();
                    };
+
+                   //Saving from current graph is done -> refresh it
                    hubber.client.savingCurrentDone = function () {
                        vm.calendarSaver = false;
@@ -41,4 +43,6 @@
                        $scope.$apply();
                    };
+
+                   //Saving all graphs done -> clear everything
                    hubber.client.savingAllDone = function () {
                        vm.calendarSaver = false;
@@ -46,4 +50,6 @@
                        $scope.$apply();
                    };
+
+                   //Dispose toggle refresh for current
                    hubber.client.processDispose = function (disp) {
                        vm.treeview.currentNode.IsDisposable = disp;
@@ -51,4 +57,6 @@
                        $scope.$apply();
                    }
+
+                   //Permissions refresh for specific resource 
                    hubber.client.processPermissions = function (id, perm) {
                        var json = JSON.parse(perm);
@@ -59,4 +67,6 @@
                        $scope.$apply();
                    }
+
+                   //Process downtimes for a resource. Data conversion
                    hubber.client.processDowntime = function (id, down) {
                        var json = JSON.parse(down);
@@ -98,11 +108,101 @@
                    }
 
+                   //Initial function to build the resource tree
+                   $scope.buildTree = function () {
+                       vm.tree = [];
+                       vm.temptree = [];
+                       vm.top = false;
+                       var ungrouped = {
+                           children: [],
+                           Name: 'Ungrouped'
+                       }
+                       for (; vm.data.length > 0;) {
+
+                           if (vm.data[0].ParentResourceId == null && vm.data[0].IsDisposable !== undefined) {
+                               var curr = $scope.seekChildren(vm.data.splice(0, 1)[0]);
+                               vm.clients.push(curr);
+                               ungrouped.children.push(curr);
+                           }
+                           else if (vm.data[0].ParentResourceId == null) {
+                               var curr = $scope.seekChildren(vm.data.splice(0, 1)[0]);
+                               vm.groups.push(curr);
+                               vm.tree.push(curr);
+                           }
+                           else {
+                               var curr = $scope.seekChildren(vm.data.splice(0, 1)[0]);
+                               if (curr.IsDisposable !== undefined)
+                                   vm.clients.push(curr);
+                               else
+                                   vm.groups.push(curr);
+                               vm.temptree.push(curr);
+                           }
+                       }
+                       vm.tree.push(ungrouped);
+
+                   };//End for hubber init
+
+                   //menu navigation
+                   $scope.menuchange = function (i) {
+                       switch (i) {
+                           case 0:
+                               $scope.permissionview = false;
+                               $scope.resaddview = false;
+                               break;
+                           case 1:
+                               $scope.permissionview = true;
+                               $scope.resaddview = false;
+                               break;
+                           case 2:
+                               $scope.permissionview = false;
+                               $scope.resaddview = true;
+                               break;
+                       }
+                   }
+
+                   //Seeks for children, used recursively for building the treeview
+                   $scope.seekChildren = function (current) {
+                       current.calendar = [];
+                       current.children = [];
+                       current.todelete = [];
+                       current.changes = false;
+                       current.collapsed = true;
+                       for (var t = 0; t < vm.temptree.length;) {
+                           if (current.Id == vm.temptree[t].ParentResourceId) {
+                               current.children.push(vm.temptree.splice(t, 1)[0]);
+                           }
+                           else {
+                               t++;
+                           }
+                       }
+                       var childc = current.children.length;//Remembers count of children received from temp tree;
+                       for (var t = 0; t < vm.data.length;) {
+                           if (current.Id == vm.data[t].ParentResourceId) {
+                               if (vm.data[t].IsDisposable !== undefined)
+                                   vm.clients.push(vm.data[t]);
+                               else
+                                   vm.groups.push(vm.data[t]);
+                               current.children.push(vm.data.splice(t, 1)[0]);
+                           }
+                           else {
+                               t++;
+                           }
+                       }
+                       for (var t = childc; t < current.children.length; t++) {
+                           current.children[t] = $scope.seekChildren(current.children[t]);
+                       }
+                       return current;
+                   }
+
+                   //Change to another resource
                    $scope.$watch("treeview.currentNode", function (newValue, oldValue) {
                        $scope.currentcal = [];
+                       $scope.resaddview = false;
                        $(".selected.ng-binding").addClass('loaded');
                        $scope.selectedEventId = -1;
                        
+                       //Check if resource already has downtime data loaded
                        if ($scope.treeview.currentNode != null && $scope.treeview.currentNode.Id != undefined) {
                            if ($scope.treeview.currentNode.calendar.length === 0) {
+                               //Reach out to server to receive resource data
                                hubber.server.requestPermissions(vm.treeview.currentNode.Id);
                                hubber.server.requestDownTime(vm.treeview.currentNode.Id);
@@ -112,12 +212,27 @@
                                $timeout(function () {
                                    refreshPermissions();
+                                   //set previously loaded data
                                    $scope.currentcal = $scope.treeview.currentNode.calendar;
                                }, 0);
 
                            }
-                       }
-
-                   });
-               }
+                           $scope.refreshAdds();
+                       }
+
+                   });
+               }
+
+               //Resets the add resources menu 
+               $scope.refreshAdds = function() {
+                   for (var i = 0; i < $scope.clients.length; i++) {
+                       $scope.clients[i].add = false;
+                       for (var j = 0; j < $scope.treeview.currentNode.children.length; j++) {
+                           if ($scope.clients[i].Id === $scope.treeview.currentNode.children[j].Id)
+                               $scope.clients[i].add = true;
+                       }
+                   }
+               }
+
+               //Resets the permissions menu
                function refreshPermissions() {
                    for (var i = 0; i < $scope.permUsers.length; i++){
@@ -136,4 +251,6 @@
                    }
                }
+
+               //Add resource group show by clearing the tree
                $scope.clearTreeSelect = function () {
                    if (vm.treeview.currentNode != undefined) {
@@ -143,73 +260,12 @@
                    }
                }
-               $scope.buildTree = function () {
-                   vm.tree = [];
-                   vm.temptree = [];
-                   vm.top = false;
-                   var ungrouped = {
-                       children: [],
-                       Name: 'Ungrouped'
-                   }
-                   for (; vm.data.length > 0;) {
-
-                       if (vm.data[0].ParentResourceId == null && vm.data[0].IsDisposable !== undefined) {
-                           var curr = $scope.seekChildren(vm.data.splice(0, 1)[0]);
-                           vm.clients.push(curr);
-                           ungrouped.children.push(curr);
-                       }
-                       else if (vm.data[0].ParentResourceId == null) {
-                           var curr = $scope.seekChildren(vm.data.splice(0, 1)[0]);
-                           vm.groups.push(curr);
-                           vm.tree.push(curr);
-                       }
-                       else {
-                           var curr = $scope.seekChildren(vm.data.splice(0, 1)[0]);
-                           if (curr.IsDisposable !== undefined)
-                               vm.clients.push(curr);
-                           else
-                               vm.groups.push(curr);
-                           vm.temptree.push(curr);
-                       }
-                   }
-                   vm.tree.push(ungrouped);
-
-               };
-
-               $scope.seekChildren = function (current) {
-                   current.calendar = [];
-                   current.children = [];
-                   current.todelete = [];
-                   current.changes = false;
-                   current.collapsed = true;
-                   for (var t = 0; t < vm.temptree.length;) {
-                       if (current.Id == vm.temptree[t].ParentResourceId) {
-                           current.children.push(vm.temptree.splice(t, 1)[0]);
-                       }
-                       else {
-                           t++;
-                       }
-                   }
-                   var childc = current.children.length;//Remembers count of children received from temp tree;
-                   for (var t = 0; t < vm.data.length;) {
-                       if (current.Id == vm.data[t].ParentResourceId) {
-                           if (vm.data[t].IsDisposable !== undefined)
-                               vm.clients.push(vm.data[t]);
-                           else
-                               vm.groups.push(vm.data[t]);
-                           current.children.push(vm.data.splice(t, 1)[0]);
-                       }
-                       else {
-                           t++;
-                       }
-                   }
-                   for (var t = childc; t < current.children.length; t++) {
-                       current.children[t] = $scope.seekChildren(current.children[t]);
-                   }
-                   return current;
-               }
+
+               //Reach out to server to toggle disposable for current calendar
                $scope.toggleDisposable = function () {
                    $scope.calendarDispose = true;
                    hubber.server.toggleDisposable(vm.treeview.currentNode.Id);
                }
+
+               //Pushes permissions to server
                $scope.pushPermissions = function () {
                    var perms = [];
@@ -226,4 +282,6 @@
                    hubber.server.changePermissions(perms, node.Id);
                }
+
+               //Collects all data from a single resource to save to the server
                function collectInfoToSave(node, refresh, last) {
                    var arr = node.calendar.down[0];
@@ -233,4 +291,5 @@
                    for (var i = 0; i < arr.length; i++) {
                        if (arr[i].id === '00000000-0000-0000-0000-000000000000') {
+                           //NEW DOWNTIME
                            var t = arr[i].allDay.toString();
                            toadd.push([
@@ -250,4 +309,5 @@
                        }
                        else if (arr[i].changed === true) {
+                           //EDIT EXISTING DOWNTIME
                            var t = arr[i].allDay.toString();
                            toupd.push([
@@ -269,9 +329,13 @@
                    hubber.server.saveCalendar(node.Id, todel, toadd, toupd, refresh, last);
                }
+
+               //Save current calendar
                $scope.saveCurrentCalendar = function () {
                    vm.calendarSaver = true;
-                   collectInfoToSave(vm.treeview.currentNode, true, false);
+                   collectInfoToSave(vm.treeview.currentNode, true, false);//true for refresh, false for save all
                    //true for refresh, false for showing it's only one calendar saved.
                }
+
+               //Save all changed calendars
                $scope.saveAllCalendars = function () {
 
@@ -289,4 +353,5 @@
                    }).then(function (success) {
                        vm.calendarSaver = true;
+
                        for (var i = 0; i < $scope.allSave.length; i++) {
                            if (i >= $scope.allSave.length - 1)
@@ -299,4 +364,6 @@
 
                }
+
+               //Checks treeview for edits and builds new array containing these (recurse for children)
                function createSaveRequests(node) {
                    if (node.changes === true)
@@ -306,4 +373,6 @@
                    }
                }
+
+               //Clears and refreshes calendar for current resource (delete current changes)
                $scope.clearCurrentCalendar = function () {
 
@@ -319,4 +388,6 @@
 
                }
+
+               //Clears all calendars and refreshes current (Deletes all changes)
                $scope.clearAllCalendars = function () {
                    ngDialog.openConfirm({
@@ -333,4 +404,6 @@
 
                }
+
+               //Function that clears all calendar (separate so dialog is not called when saveAll is finished)
                function clearAllCalendarsFunc() {
                    $(".ng-binding.changed").removeClass('changed');
@@ -347,4 +420,6 @@
                    $(".selected.ng-scope").addClass('loaded');
                }
+
+               //Recurse trough tree view
                function clearCalendarsRecurse(node) {
 
@@ -356,4 +431,6 @@
                    }
                }
+
+               //Delete all downtimes from current resource
                $scope.deleteAllEvents = function () {
                    vm.calendarDeleter = true;
@@ -373,4 +450,6 @@
                    });
                }
+
+               //Delete all past events
                $scope.deleteAllPreviousEvents = function () {
                    vm.calendarDeleter = true;
@@ -395,5 +474,5 @@
                }
 
-
+               //Sets the status of a downtime AND the current resource to changed
                $scope.setChanged = function (id) {
                    if (id != -1) {
@@ -408,5 +487,6 @@
                    $(".selected").addClass('changed');
                }
-               //*Add event by click
+
+               //Adds event by click on empty space
                $scope.calendarClick = function (date, jsEvent, view) {
 
@@ -418,5 +498,5 @@
                    end.setHours(dat.getHours() + 2);
                    vm.treeview.currentNode.calendar.down[0].push({
-                       id: '00000000-0000-0000-0000-000000000000',
+                       id: '00000000-0000-0000-0000-000000000000',//Makes it recognizable as new for the server
                        title: 'Unavailable',
                        start: dat,
@@ -440,4 +520,6 @@
 
                }
+
+               //Finds array index for specific _id
                function checkId(id) {
                    for (var i = 0; i < vm.treeview.currentNode.calendar.down[0].length ; i++) {
@@ -447,13 +529,15 @@
                    return -1;
                }
-               /* alert on eventClick */
+               //Set selected downtime
                $scope.eventClick = function (date, jsEvent, view) {
                    vm.selectedEventId = checkId(date._id);
                };
+               //Sets selected downtime by clicking on the button at bottom on the page, moves to date
                $scope.eventClickBtn = function (id) {
                    vm.selectedEventId = checkId(id);
                    vm.goToDate();
                };
-               /* alert on Drop */
+
+               //Drag and drop downtime
                $scope.dragandDrop = function (event, delta, revertFunc, jsEvent, ui, view) {
                    vm.selectedEventId = checkId(event._id);
@@ -474,5 +558,5 @@
                    vm.treeview.currentNode.calendar.down[0][vm.selectedEventId].end = new Date(event.end);
                };
-               /* alert on Resize */
+               //Resize downtime
                $scope.resizeEvent = function (event, delta, revertFunc, jsEvent, ui, view) {
                    vm.selectedEventId = checkId(event._id);
@@ -482,5 +566,5 @@
                };
 
-               /* remove event */
+               //Removes a downtime from client (existing downtime gets referenced in todelete
                $scope.remove = function (index) {
                    vm.selectedEventId = -1;
@@ -493,4 +577,5 @@
 
                };
+               //Remove trough list view at bottom
                $scope.removeList = function (id) {
                    var index = checkId(id);
@@ -504,5 +589,5 @@
 
                };
-
+               //Check if start is before end AND start is after now (recursion)
                $scope.checkDateStartEnd = function () {
                    if ($scope.currentcal.down[0][vm.selectedEventId].rec.start > $scope.currentcal.down[0][vm.selectedEventId].rec.end ||
@@ -515,5 +600,5 @@
                        $scope.currentcal.down[0][vm.selectedEventId].rec.start = new Date();
                }
-               //pushes all changes to other recurs
+               //pushes all changes to other existing recurs and creates new downtimes where needed
                $scope.pushRecurChanges = function (recid) {
                    ngDialog.openConfirm({
@@ -526,17 +611,22 @@
                        plain: true
                    }).then(function (success) {
+
                        var arr = vm.treeview.currentNode.calendar.down[0];
+                       //Deep copy of downtime for referencing
                        var ob = $.extend(true, {}, arr[vm.selectedEventId]);
-                       for (var i = 0; i < arr.length;) {
+
+                       for (var i = 0; i < arr.length;) {//Go trough downtimes and find all recurrences
                            if (arr[i].rec.recid === recid) {
                                if (new Date(arr[i].start) < new Date(ob.rec.start) ||
                                         new Date(arr[i].end) > new Date(ob.rec.end) ||
                                         !ob.rec.days[new Date(arr[i].start).getDay()]) {
-                                   vm.remove(i);
+                                   //Downtime is out of recurrence boundaries
+                                   //Before start date OR After end date OR Not on right day of the week
+                                   vm.remove(i);//NO I++ -> REMOVE SPLICES ARRAY
                                    vm.selectedEventId = -1;
 
                                }
                                else {
-
+                                   //Edit downtime when it is within the bounds
                                    arr[i].start.setHours(ob.start.getHours(), ob.start.getMinutes());
                                    arr[i].end.setHours(ob.end.getHours(), ob.end.getMinutes());
@@ -551,14 +641,16 @@
                                i++;
                        }
+                       //init for new downtimes. 
                        var start = new Date(ob.rec.start);
-                       start.setHours(2, 0, 0, 0);
+                       start.setHours(2, 0, 0, 0);//Beginning of the day + time conversion +02
                        var end = new Date(ob.rec.end);
-                       end = new Date(end.setHours(24, 0, 0, 0) + 1000 * 3600 * 2);
-
-                       loop1:
+                       end = new Date(end.setHours(24, 0, 0, 0) + 1000 * 3600 * 2);//End of the day + time conversion +02
+
+                       loop1: //Loop start to end with single day increment
                            for (var d = (start.getTime()) ; d < (end.getTime()) ;) {
                                var tog = ob.rec.days[new Date(d).getDay()];
+                               //Check if day of the week is included in recursion
                                if (tog) {
-                                   loop2:
+                                   loop2://Loop checking existing downtime array to see if day is already filled or not
                                        for (var i = 0; i < arr.length; i++) {
 
@@ -567,10 +659,10 @@
                                                if (arr[i].start.getTime() >= d &&
                                                    arr[i].end.getTime() <= dend) {
-                                                   d += (1000 * 3600 * 24);
-                                                   continue loop1;
+                                                   d += (1000 * 3600 * 24);//add day to loop 1
+                                                   continue loop1;//breaks out of loop2 and skips to next day
                                                }
                                            }
                                        }
-
+                                   //Made it here = new event needed: init
                                    var ts = new Date(d);
                                    ts.setHours(new Date(ob.start).getHours(), new Date(ob.start).getMinutes());
@@ -589,9 +681,11 @@
                                }
 
-                               d += (1000 * 3600 * 24);// 1 day
-
-                           }
-                   });
-               }
+                               d += (1000 * 3600 * 24);// adds one day
+
+                           }
+                   });
+               }
+
+               //Delete all bound recurrences
                $scope.deleteAllRecurrences = function (recid) {
                    ngDialog.openConfirm({
@@ -614,8 +708,9 @@
                }
 
+               //Moves calendar to selected date
                $scope.goToDate = function () {
                    $("#resourcecalendar").fullCalendar('gotoDate', vm.currentcal.down[0][vm.selectedEventId].start);
                }
-               /* Render Tooltip */
+               /* Renders Tooltip */
                $scope.eventRender = function (event, element, view) {
                    element.attr({
@@ -625,5 +720,5 @@
                    //$compile(element)($scope);
                };
-               /* config object */
+               //Calendar configuration
                $scope.uiConfig = {
                    calendar: {
@@ -650,12 +745,14 @@
                };
 
+               
+
 
 
            }).filter('disp', function () {
-               return function (input) {
+               return function (input) {//Filter boolean to string
                    return input ? 'Disposable' : 'Not disposable';
                }
            }).directive('animateOnChange', function ($timeout) {
-               return function (scope, element, attr) {
+               return function (scope, element, attr) {//Animation on downtime info to show change
                    scope.$watch(attr.animateOnChange, function (nv, ov) {
 
@@ -665,5 +762,5 @@
                                $timeout(function () {
                                    element.removeClass('changed');
-                               }, 250); // Could be enhanced to take duration as a parameter
+                               }, 250); 
                            }
                            else {
@@ -671,5 +768,5 @@
                                $timeout(function () {
                                    element.removeClass('changedshut');
-                               }, 250); // Could be enhanced to take duration as a parameter
+                               }, 250);
                            }
                        }
Index: /branches/WebJobManager/HeuristicLab.Clients.Hive.WebJobManager/Scripts/Hubs/UserInfoHubber.js
===================================================================
--- /branches/WebJobManager/HeuristicLab.Clients.Hive.WebJobManager/Scripts/Hubs/UserInfoHubber.js	(revision 13804)
+++ /branches/WebJobManager/HeuristicLab.Clients.Hive.WebJobManager/Scripts/Hubs/UserInfoHubber.js	(revision 13805)
@@ -2,5 +2,5 @@
 
 $(function () {
-    $.connection.hub.logging = true;
+    //$.connection.hub.logging = true;
     var v = document.getElementById("userId").innerHTML;
     console.log(v);
@@ -8,5 +8,5 @@
     $.connection.hub.start();
     hubber.client.showNewPass = function (pass) {
-        $("#inppassreset").html("<label class=' control-label' style='text-align:left'>New password: " + pass + "</label>");
+        $("#inppassreset").html("<label class=' control-label' style='text-align:left'>New pass: " + pass + ". An email has been sent to the user containing the new password</label>");
                                       
     };
Index: /branches/WebJobManager/HeuristicLab.Clients.Hive.WebJobManager/Scripts/Styling/angular.treeview.css
===================================================================
--- /branches/WebJobManager/HeuristicLab.Clients.Hive.WebJobManager/Scripts/Styling/angular.treeview.css	(revision 13804)
+++ /branches/WebJobManager/HeuristicLab.Clients.Hive.WebJobManager/Scripts/Styling/angular.treeview.css	(revision 13805)
@@ -61,5 +61,5 @@
 
     div[data-tree-model] li.selected {
-        box-shadow:  2px 3px 5px rgba(0,0,0,0.6), inset 1px 10px 300px 51px rgba(143,201,58,1)!important;
+        box-shadow:  2px 3px 5px rgba(0,0,0,0.6), inset 1px 10px 300px 51px #5cb85c!important;
     }
     div[data-tree-model] span.selected {
Index: /branches/WebJobManager/HeuristicLab.Clients.Hive.WebJobManager/Services/Imports/AccessAdministrationClient.cs
===================================================================
--- /branches/WebJobManager/HeuristicLab.Clients.Hive.WebJobManager/Services/Imports/AccessAdministrationClient.cs	(revision 13804)
+++ /branches/WebJobManager/HeuristicLab.Clients.Hive.WebJobManager/Services/Imports/AccessAdministrationClient.cs	(revision 13805)
@@ -31,4 +31,7 @@
 namespace HeuristicLab.Clients.Access.Administration
 {
+    /// <summary>
+    /// Controls everything User/Group/Role related
+    /// </summary>
     [Item("AccessAdministrationClient", "AccessAdministration client.")]
     public class AccessAdministrationClient : IContent
Index: /branches/WebJobManager/HeuristicLab.Clients.Hive.WebJobManager/Services/WebLoginService.cs
===================================================================
--- /branches/WebJobManager/HeuristicLab.Clients.Hive.WebJobManager/Services/WebLoginService.cs	(revision 13804)
+++ /branches/WebJobManager/HeuristicLab.Clients.Hive.WebJobManager/Services/WebLoginService.cs	(revision 13805)
@@ -124,8 +124,18 @@
         }
 
+        /// <summary>
+        /// Returns the AccessAdministrationClient used for User/Group/Role management 
+        /// </summary>
+        /// <param name="id"></param>
+        /// <returns></returns>
         public AccessAdministrationClient getAccessAdminClient(Guid id)
         {
             return accessclients.Find(x => x.userId == id);
         }
+        /// <summary>
+        /// Returns HiveAdminClient used for Resource management
+        /// </summary>
+        /// <param name="id"></param>
+        /// <returns></returns>
         public HiveAdminClientWeb getAdminClient(Guid id)
         {
Index: /branches/WebJobManager/HeuristicLab.Clients.Hive.WebJobManager/ViewModels/User/UserViewModel.cs
===================================================================
--- /branches/WebJobManager/HeuristicLab.Clients.Hive.WebJobManager/ViewModels/User/UserViewModel.cs	(revision 13804)
+++ /branches/WebJobManager/HeuristicLab.Clients.Hive.WebJobManager/ViewModels/User/UserViewModel.cs	(revision 13805)
@@ -7,4 +7,7 @@
 namespace HeuristicLab.Clients.Hive.WebJobManager.ViewModels.User
 {
+    /// <summary>
+    /// ViewModel containing User/Group/Role data
+    /// </summary>
     public class UserViewModel
     {
@@ -24,4 +27,8 @@
         public List<Access.UserGroupBase> SelectedRoleEnrolled { get; set; }
 
+        /// <summary>
+        /// Initialize viewmodel and set up connection
+        /// </summary>
+        /// <param name="ac">AccessAdminClient for connection</param>
         public UserViewModel(AccessAdministrationClient ac)
         {
@@ -40,4 +47,8 @@
             
         }
+        /// <summary>
+        /// Refreshes Users, Groups and Roles
+        /// </summary>
+        /// <returns></returns>
         public UserViewModel refreshAll()
         {
@@ -47,4 +58,8 @@
             return this;
         }
+        /// <summary>
+        /// Refreshes only the Users
+        /// </summary>
+        /// <returns></returns>
         public UserViewModel refreshUsers()
         {
@@ -53,4 +68,8 @@
             return this;
         }
+        /// <summary>
+        /// Refreshes only the Roles
+        /// </summary>
+        /// <returns></returns>
         public UserViewModel refreshRoles()
         {
@@ -59,4 +78,8 @@
             return this;
         }
+        /// <summary>
+        /// Refreshes only the User Groups
+        /// </summary>
+        /// <returns></returns>
         public UserViewModel refreshGroups()
         {
@@ -65,12 +88,27 @@
             return this;
         }
+        /// <summary>
+        /// Returns a user by its Id
+        /// </summary>
+        /// <param name="id">User Id</param>
+        /// <returns></returns>
         public Access.User getUserById(Guid id)
         {
             return users.Find(x => x.Id == id);
         }
+        /// <summary>
+        /// Returns a group by its Id
+        /// </summary>
+        /// <param name="id">Group id</param>
+        /// <returns></returns>
         public Access.UserGroup getGroupById(Guid id)
         {
             return ugroups.Find(x => x.Id == id);
         }
+        /// <summary>
+        /// Returns a role by its name
+        /// </summary>
+        /// <param name="name">Role name</param>
+        /// <returns></returns>
         public Access.Role getRoleByName(string name)
         {
Index: /branches/WebJobManager/HeuristicLab.Clients.Hive.WebJobManager/Views/Resource/Index.cshtml
===================================================================
--- /branches/WebJobManager/HeuristicLab.Clients.Hive.WebJobManager/Views/Resource/Index.cshtml	(revision 13804)
+++ /branches/WebJobManager/HeuristicLab.Clients.Hive.WebJobManager/Views/Resource/Index.cshtml	(revision 13805)
@@ -8,5 +8,5 @@
 
     <div class="col-sm-4">
-        <div class="btn-group btn-group-justified" style="padding:3px;margin-bottom:-10px"
+        <div class="btn-group btn-group-justified" style="padding:3px;margin-bottom:-12px"
              role="group">
             <a class="btn btn-info btn-lg btn-block disabled"
@@ -48,33 +48,90 @@
             </h3>
             <ul class="nav nav-pills nav-justified">
-                <li role="presentation" ng-class="{ 'active': !permission }" ng-style="{ 'text-decoration': !permission ? 'underline' : ''}">
+                <li role="presentation"
+                    ng-class="{ 'active': !permissionview && !resaddview }"
+                    ng-style="{ 'text-decoration': !permissionview && !resaddview ? 'underline' : ''}">
                     <a style="text-shadow:2px 2px black; color:white; font-weight:bold; border: 1px solid white;"
                        href=""
-                       ng-click="permission = false">
+                       ng-click="menuchange(0)">
                         Resource info
                     </a>
                 </li>
-                <li role="presentation" ng-class="{ 'active': permission }" ng-style="{ 'text-decoration': permission ? 'underline' : ''}">
+                <li role="presentation"
+                    ng-class="{ 'active': permissionview }"
+                    ng-style="{ 'text-decoration': permissionview ? 'underline' : ''}">
                     <a style="text-shadow:2px 2px black; color:white; font-weight:bold; border: 1px solid white;"
                        href=""
-                       ng-click="permission = true">
+                       ng-click="menuchange(1)">
                         Permissions
                     </a>
                 </li>
+                <li ng-if="treeview.currentNode.IsDisposable === undefined"
+                    role="presentation"
+                    ng-class="{ 'active': resaddview }"
+                    ng-style="{ 'text-decoration': resaddview ? 'underline' : ''}">
+
+                    <a style="text-shadow:2px 2px black; color:white; font-weight:bold; border: 1px solid white;"
+                       href=""
+                       ng-click="menuchange(2)">
+                        Add resources
+                    </a>
+                </li>
             </ul>
-            
-            <form ng-show="permission"
+            <form ng-show="!permissionview && resaddview"
                   method="post"
-                  asp-action="editPermissions"
+                  asp-action="addResourcesToGroup"
                   asp-controller="Resource"
                   enctype="multipart/form-data"
-                  class="row panel-heading"
-                  > 
-                <div
-                     class="row" style="padding:10px;">
+                  class="row panel-heading">
+                <div class="row" style="padding:5px;">
+                    <h4>Info</h4>
+                    <p>
+                        This shows only
+                        <span style="text-decoration:underline">direct members</span>
+                        of the group (not members of subgroups).
+                    </p>
+                    <p>Adding a member will overwrite the current group it's a member in (if any)</p>
+                    <p>Removing an existing member will make it revert to Ungrouped.</p>
+                    <a ng-click="refreshAdds()" href=""
+                       class="btn btn-info pull-right"
+                       style="box-shadow: 0 4px 8px 0 rgba(0, 0, 0, 0.2), 0 6px 20px 0 rgba(0, 0, 0, 0.19);
+                            text-shadow:2px 2px black;">Reset to current members</a>
+                    <div class="row" style="margin:5px">
+                        <h4>All resources</h4>
+                        <label class="col-sm-3"
+                               ng-style="{
+                                   'background-color':client.add === true ? 'green' : '' }"
+                               ng-repeat="client in clients  | orderBy:['!add', 'Name' ]  | filter:searchText">
+                            <input type="checkbox"
+                                   name="addres"
+                                   value="{{client.Id}}"
+                                   ng-model="client.add"> {{client.Name}}
+                        </label>
+                    </div>
+                </div>
+                <input style="display:none"
+                       type="text"
+                       id="groupid"
+                       name="groupid"
+                       value="{{treeview.currentNode.Id}}" />
+
+                <button type="submit"
+                        id="inpsaver"
+                        class="btn btn-success pull-right"
+                        style="box-shadow: 0 4px 8px 0 rgba(0, 0, 0, 0.2), 0 6px 20px 0 rgba(0, 0, 0, 0.19);
+                            text-shadow:2px 2px black;">
+                    <i class="fa fa-save"></i>
+                    Add resources to group
+                </button>
+            </form>
+            <form ng-show="permissionview && !resaddview"
+                  method="post"
+                  enctype="multipart/form-data"
+                  class="row panel-heading">
+                <div class="row" style="padding:10px;">
                     <h4>Groups</h4>
                     <label class="col-sm-3" ng-repeat="group in permGroups">
-                        <input type="checkbox" 
-                               name="permgroups" 
+                        <input type="checkbox"
+                               name="permgroups"
                                value="{{group.Id}}"
                                ng-model="group.state"> {{group.Name}}
@@ -84,18 +141,19 @@
                     <h4>Users</h4>
                     <label class="col-sm-3 col-lg-2" ng-repeat="user in permUsers">
-                        <input type="checkbox" 
-                               name="permusers" 
+                        <input type="checkbox"
+                               name="permusers"
                                value="{{user.Id}}"
                                ng-model="user.state"> {{user.UserName}}
                     </label>
                 </div>
-                <div class="btn btn-info pull-right" 
+                <div class="btn btn-success pull-right"
                      style="box-shadow: 0 4px 8px 0 rgba(0, 0, 0, 0.2), 0 6px 20px 0 rgba(0, 0, 0, 0.19);
                             text-shadow:2px 2px black;"
                      ng-click="pushPermissions()">
-                <i ng-if="permissionLoader" class="fa fa-spin fa-save"></i> 
-                Save permission changes</div>
+                    <i ng-if="permissionLoader" class="fa fa-spin fa-save"></i>
+                    Save permission changes
+                </div>
             </form>
-            <form ng-show="!permission"
+            <form ng-show="!permissionview && !resaddview"
                   method="post"
                   asp-action="deleteClientGroup"
@@ -155,5 +213,5 @@
                         <tr>
                             <td>Memory (free/total)</td>
-                            <td>{{treeview.currentNode.FreeMemory/1024 | number:1}} GB / {{treeview.currentNode.Memory/1024 | number:1}} GB</td>
+                            <td>{{treeview.currentNode.FreeMemory/1024 | number:1}} / {{treeview.currentNode.Memory/1024 | number:1}} GB</td>
                         </tr>
 
@@ -161,5 +219,5 @@
                 </table>
             </form>
-            <form method="post"
+            <form method="post" ng-show="!permissionview && !resaddview"
                   asp-action="changeParent"
                   asp-controller="Resource"
@@ -169,5 +227,5 @@
                 <input style="display:none" type="text" id="inpid" name="inpid" value="{{treeview.currentNode.Id}}" />
 
-                <span style="padding:0px" class="col-sm-4">Change parent resource: </span>
+                <span style="padding:0px" class="col-sm-4">Change group: </span>
 
                 <select class="form-control col-sm-5"
@@ -190,5 +248,5 @@
                             text-shadow:2px 2px black;">
                     <i class="fa fa-save"></i>
-                    Change parent
+                    Change group
                 </button>
             </form>
@@ -485,16 +543,22 @@
                 <h3>Choose resources </h3>
                 <h5>(This will overwrite the group set for these resources)</h5>
-                <table>
-                    <tr ng-repeat="client in clients  | orderBy:['Name'] track by $index" class="checkbox col-md-6 col-lg-4">
-                        <td>
-                            <label>
-                                <input type="checkbox"
-                                       name="clientstoadd"
-                                       value="{{client.Id}}">
-                                <i class="fa fa-desktop" aria-hidden="true"></i> {{client.Name | limitTo : 7}} - {{client.Cores}}x {{client.CpuSpeed/1000 |  number:1}} GHz - {{client.Memory / 1024 | number:1}} GB
-                            </label>
-                        </td>
-                    </tr>
-                </table>
+                <label>Search: <input ng-init="searchText = ''" ng-model="searchText"></label>
+                <div class="row">
+                    <div style="margin:0px"
+                         ng-repeat="client in clients  | orderBy:['Name']  | filter:searchText" class="checkbox col-md-6 col-lg-4">
+
+                        <label ng-style="{
+                                   'background-color':client.checked === true ? 'green' : '',
+                                    'color':client.checked === true ? 'white' : ''  }"
+                               style="border-radius:5px">
+                            <input type="checkbox"
+                                   name="clientstoadd"
+                                   ng-model="client.checked"
+                                   value="{{client.Id}}" />
+                            <i class="fa fa-desktop" aria-hidden="true"></i> {{client.Name | limitTo : 7}} - {{client.Cores}}x {{client.CpuSpeed/1000 |  number:1}} GHz - {{client.Memory / 1024 | number:1}} GB
+                        </label>
+
+                    </div>
+                </div>
             </div>
         </form>
Index: /branches/WebJobManager/HeuristicLab.Clients.Hive.WebJobManager/Views/User/Groups.cshtml
===================================================================
--- /branches/WebJobManager/HeuristicLab.Clients.Hive.WebJobManager/Views/User/Groups.cshtml	(revision 13804)
+++ /branches/WebJobManager/HeuristicLab.Clients.Hive.WebJobManager/Views/User/Groups.cshtml	(revision 13805)
@@ -37,7 +37,9 @@
          style="padding:10px; margin-right:0px!important">
         <div class="col-sm-4">
-            <div class="btn-group-vertical btn-block">
+            <div class="btn-group btn-group-justified btn-block"
+                 role="group" style="margin-bottom:-4px">
+
                 <a class="btn btn-info btn-lg btn-block disabled"
-                   style="box-shadow: 0 4px 8px 0 rgba(0, 0, 0, 0.2), 0 6px 20px 0 rgba(0, 0, 0, 0.19);
+                   style="width:6%;box-shadow: 0 4px 8px 0 rgba(0, 0, 0, 0.2), 0 6px 20px 0 rgba(0, 0, 0, 0.19);
                             text-shadow:2px 2px black;">
                     <i class="fa fa-group"></i> @Model.ugroups.Count Group@(Model.ugroups.Count != 1 ? "s" : "")
@@ -52,6 +54,9 @@
                    style="box-shadow: 0 4px 8px 0 rgba(0, 0, 0, 0.2), 0 6px 20px 0 rgba(0, 0, 0, 0.19);
                             text-shadow:2px 2px black;">
-                    <i class="fa fa-plus-circle"></i> Add new group
+                    <i class="fa fa-plus-circle"></i> 
                 </a>
+            </div>
+            <div class="btn-group-vertical btn-block">
+                
                 @foreach (var group in Model.ugroups)
                 {
@@ -128,5 +133,9 @@
                                 </div>
                             </div>
-
+                            <input type="text"
+                                   style="display:none"
+                                   id="u"
+                                   name="u"
+                                   value="@Model.SelectedGroup.Id" />
 
                             @if (Model.SelectedGroup.Id != Guid.Empty)
Index: /branches/WebJobManager/HeuristicLab.Clients.Hive.WebJobManager/Views/User/Index.cshtml
===================================================================
--- /branches/WebJobManager/HeuristicLab.Clients.Hive.WebJobManager/Views/User/Index.cshtml	(revision 13804)
+++ /branches/WebJobManager/HeuristicLab.Clients.Hive.WebJobManager/Views/User/Index.cshtml	(revision 13805)
@@ -47,21 +47,27 @@
         {
             <div class="col-sm-4">
-                <div class="btn-group-vertical btn-block">
-                    <a class="btn btn-info btn-lg btn-block disabled"
-                       style="box-shadow: 0 4px 8px 0 rgba(0, 0, 0, 0.2), 0 6px 20px 0 rgba(0, 0, 0, 0.19);
+                <div class="btn-group btn-group-justified btn-block"
+                     role="group" style="margin-bottom:-4px">
+
+                    <a class="btn btn-info btn-lg disabled"
+                       style="width:6%;box-shadow: 0 4px 8px 0 rgba(0, 0, 0, 0.2), 0 6px 20px 0 rgba(0, 0, 0, 0.19);
                             text-shadow:2px 2px black;">
                         <i class="fa fa-user"></i> @Model.users.Count User@(Model.users.Count != 1 ? "s" : "")
                     </a>
-                    <a class="btn btn-success btn-block
+                    <a class="btn btn-success
                        @(Model.SelectedUser.Id == Guid.Empty ? "active" : "")
                        "
+                       style="box-shadow: 0 4px 8px 0 rgba(0, 0, 0, 0.2), 0 6px 20px 0 rgba(0, 0, 0, 0.19);
+                            text-shadow:2px 2px black;"
                        asp-controller="User"
                        asp-action="SelectUser"
                        asp-route-id="@Guid.Empty"
-                       onclick="showUser()"
-                       style="box-shadow: 0 4px 8px 0 rgba(0, 0, 0, 0.2), 0 6px 20px 0 rgba(0, 0, 0, 0.19);
-                            text-shadow:2px 2px black;">
-                        <i class="fa fa-user-plus"></i> Add new user
+                       onclick="showUser()">
+                        <i class="fa fa-user-plus"></i>
                     </a>
+                </div>
+                <div class="btn-group-vertical btn-block">
+                    
+                    
                     @foreach (var user in Model.users)
                     {
@@ -119,5 +125,5 @@
                               method="post"
                               asp-action="saveUser"
-                              asp-controller="User" 
+                              asp-controller="User"
                               enctype="multipart/form-data"
                               onsubmit="showSaver()">
@@ -181,5 +187,5 @@
                                         @Model.SelectedUser.Id
                                     </label>
-                                    
+
                                 </div>
                                 <div class="form-group">
@@ -295,5 +301,5 @@
                                             {
                                                 <div class="row">
-                                                    
+
                                                     <p class="col-sm-10"><i class="fa fa-gavel"></i> @r.Name</p>
                                                     <p class="col-sm-2">
@@ -359,6 +365,5 @@
                                             id="inpsaver"
                                             disabled
-                                            class="btn btn-default"
-                                            >
+                                            class="btn btn-default">
                                         <i class="fa fa-save"></i>
                                         @(Model.SelectedUser.Id != Guid.Empty ? "Save changes" : "Add user")
Index: /branches/WebJobManager/HeuristicLab.Clients.Hive.WebJobManager/Views/User/Roles.cshtml
===================================================================
--- /branches/WebJobManager/HeuristicLab.Clients.Hive.WebJobManager/Views/User/Roles.cshtml	(revision 13804)
+++ /branches/WebJobManager/HeuristicLab.Clients.Hive.WebJobManager/Views/User/Roles.cshtml	(revision 13805)
@@ -38,7 +38,9 @@
 
         <div class="col-sm-4">
-            <div class="btn-group-vertical btn-block">
+            <div class="btn-group btn-group-justified btn-block"
+                 role="group" style="margin-bottom:-4px">
+
                 <a class="btn btn-info btn-lg btn-block disabled"
-                   style="box-shadow: 0 4px 8px 0 rgba(0, 0, 0, 0.2), 0 6px 20px 0 rgba(0, 0, 0, 0.19);
+                   style="width:6%;box-shadow: 0 4px 8px 0 rgba(0, 0, 0, 0.2), 0 6px 20px 0 rgba(0, 0, 0, 0.19);
                             text-shadow:2px 2px black;">
                     <i class="fa fa-gavel"></i> @Model.roles.Count Role@(Model.roles.Count != 1 ? "s" : "")
@@ -53,6 +55,9 @@
                    style="box-shadow: 0 4px 8px 0 rgba(0, 0, 0, 0.2), 0 6px 20px 0 rgba(0, 0, 0, 0.19);
                             text-shadow:2px 2px black;">
-                    <i class="fa fa-plus-circle"></i> Add new role
+                    <i class="fa fa-plus-circle"></i>
                 </a>
+            </div>
+            <div class="btn-group-vertical btn-block">
+                
                 @foreach (var role in Model.roles)
                 {
Index: /branches/WebJobManager/HeuristicLab.Clients.Hive.WebJobManager/wwwroot/css/site.min.css
===================================================================
--- /branches/WebJobManager/HeuristicLab.Clients.Hive.WebJobManager/wwwroot/css/site.min.css	(revision 13804)
+++ /branches/WebJobManager/HeuristicLab.Clients.Hive.WebJobManager/wwwroot/css/site.min.css	(revision 13805)
@@ -1,3 +1,3 @@
-@import url(http://fonts.googleapis.com/css?family=Roboto:400);.wrapper,h4{text-align:center}.label,sub,sup{vertical-align:baseline}[role=button],div[data-tree-model] li,div[data-tree-model] li i{cursor:pointer}.fc table,table{border-spacing:0}body,figure{margin:0}.btn-group>.btn-group,.btn-toolbar .btn,.btn-toolbar .btn-group,.btn-toolbar .input-group,.col-xs-1,.col-xs-10,.col-xs-11,.col-xs-12,.col-xs-2,.col-xs-3,.col-xs-4,.col-xs-5,.col-xs-6,.col-xs-7,.col-xs-8,.col-xs-9,.dropdown-menu{float:left}.navbar-fixed-bottom .navbar-collapse,.navbar-fixed-top .navbar-collapse,.pre-scrollable{max-height:340px}.fa,.glyphicon{-moz-osx-font-smoothing:grayscale}body{-webkit-font-smoothing:antialiased;font:400 14px Roboto,arial,sans-serif}.container{padding:25px;position:fixed}.form-login{background-color:#EDEDED;border-radius:15px;border-color:#d2d2d2;border-width:5px;box-shadow:0 1px 0 #cfcfcf;padding:10px 20px 20px;padding:10px 20px 20px}h4{border:0 solid #fff;border-bottom-width:1px;padding-bottom:10px}.panel-warning>.panel-heading{background-image:linear-gradient(to bottom,#eb9114 0,#f1b25b 100%)!important;color:#fff!important}.panel-danger>.panel-heading{background-image:linear-gradient(to bottom,#c12e2a 0,#d9534f 100%)!important;color:#fff!important}.label-as-badge{border-radius:1em}.bar-off{fill:#c2c2d6}.bar-off:hover{fill:#e0e0eb}.bar-wait{fill:#f0a742}.bar-wait:hover{fill:#f4bd71}.bar-trans{fill:#80d4ff}.bar-trans:hover{fill:#9df}.bar-calc{fill:#2f6fa6}.bar-calc:hover{fill:#3884c7}.bar-paus{fill:#47476b}.bar-paus:hover{fill:#5c5c8a}.bar-fin{fill:#5cb85c}.bar-fin:hover{fill:#71c171}.bar-abo{fill:#c2302c}.bar-abo:hover{fill:#d54944}.bar-fail{fill:#c2302c}.bar-fail:hover{fill:#d54944}rect.selection{stroke:gray;stroke-dasharray:4px;stroke-opacity:.5;fill:transparent}svg ::selection{background:0 0}svg ::-moz-selection{background:0 0}svg ::-webkit-selection{background:0 0}.btn-danger:focus,.btn-danger:hover,.btn-default:focus,.btn-default:hover,.btn-info:focus,.btn-info:hover,.btn-primary:focus,.btn-primary:hover,.btn-success:focus,.btn-success:hover,.btn-warning:focus,.btn-warning:hover{background-position:0 -15px}[animate-on-change]{transition:all 1s;-webkit-transition:all 1s}[animate-on-change].changed{background-color:#add8e6;transition:none;-webkit-transition:none}[animate-on-change].changedshut{background-color:#ffa07a;transition:none;-webkit-transition:none}.panel-heading .nav-justified.nav-pills li.active>a{background-color:#74a9d8!important}div[data-angular-treeview]{-moz-user-select:-moz-none;-khtml-user-select:none;-webkit-user-select:none;-ms-user-select:none;user-select:none;font-family:"Helvetica Neue",Helvetica,Arial,sans-serif;font-size:14px;font-weight:600;color:#fff;text-decoration:none;text-shadow:1px 1px #000}div[data-tree-model] ul{padding:5px;list-style:none;border:#778899;overflow:hidden}div[data-tree-model] li{position:relative;padding:0 0 0 20px;line-height:20px;margin-top:3px;border:#add8e6;border-radius:10px;box-shadow:2px 3px 5px rgba(0,0,0,.6),inset 1px 10px 300px 51px rgba(33,151,184,1)}div[data-tree-model] li .expanded{padding:1px 10px;background-image:url(../img/folder.png);background-repeat:no-repeat}div[data-tree-model] li .collapsed{padding:1px 10px;background-image:url(../img/folder-closed.png);background-repeat:no-repeat}div[data-tree-model] li .normal{padding:1px 10px;color:#000;background-image:url(../img/file.png);background-repeat:no-repeat}div[data-tree-model] li.selected{box-shadow:2px 3px 5px rgba(0,0,0,.6),inset 1px 10px 300px 51px rgba(143,201,58,1)!important}div[data-tree-model] span.selected{color:#fff!important;text-shadow:1px 1px #000!important;font-weight:700;padding:1px 5px}div[data-tree-model] li.changed{box-shadow:2px 3px 5px rgba(0,0,0,.6),inset 1px 10px 300px 51px rgba(250,250,210,1)}div[data-tree-model] span.changed{color:#000;text-shadow:1px 1px #fff;font-weight:700;padding:1px 5px}div[data-tree-model] span.loaded{text-decoration:underline;font-style:oblique}/*!
+@import url(http://fonts.googleapis.com/css?family=Roboto:400);.wrapper,h4{text-align:center}.label,sub,sup{vertical-align:baseline}[role=button],div[data-tree-model] li,div[data-tree-model] li i{cursor:pointer}.fc table,table{border-spacing:0}body,figure{margin:0}.btn-group>.btn-group,.btn-toolbar .btn,.btn-toolbar .btn-group,.btn-toolbar .input-group,.col-xs-1,.col-xs-10,.col-xs-11,.col-xs-12,.col-xs-2,.col-xs-3,.col-xs-4,.col-xs-5,.col-xs-6,.col-xs-7,.col-xs-8,.col-xs-9,.dropdown-menu{float:left}.navbar-fixed-bottom .navbar-collapse,.navbar-fixed-top .navbar-collapse,.pre-scrollable{max-height:340px}.fa,.glyphicon{-moz-osx-font-smoothing:grayscale}body{-webkit-font-smoothing:antialiased;font:400 14px Roboto,arial,sans-serif}.container{padding:25px;position:fixed}.form-login{background-color:#EDEDED;border-radius:15px;border-color:#d2d2d2;border-width:5px;box-shadow:0 1px 0 #cfcfcf;padding:10px 20px 20px;padding:10px 20px 20px}h4{border:0 solid #fff;border-bottom-width:1px;padding-bottom:10px}.panel-warning>.panel-heading{background-image:linear-gradient(to bottom,#eb9114 0,#f1b25b 100%)!important;color:#fff!important}.panel-danger>.panel-heading{background-image:linear-gradient(to bottom,#c12e2a 0,#d9534f 100%)!important;color:#fff!important}.label-as-badge{border-radius:1em}.bar-off{fill:#c2c2d6}.bar-off:hover{fill:#e0e0eb}.bar-wait{fill:#f0a742}.bar-wait:hover{fill:#f4bd71}.bar-trans{fill:#80d4ff}.bar-trans:hover{fill:#9df}.bar-calc{fill:#2f6fa6}.bar-calc:hover{fill:#3884c7}.bar-paus{fill:#47476b}.bar-paus:hover{fill:#5c5c8a}.bar-fin{fill:#5cb85c}.bar-fin:hover{fill:#71c171}.bar-abo{fill:#c2302c}.bar-abo:hover{fill:#d54944}.bar-fail{fill:#c2302c}.bar-fail:hover{fill:#d54944}rect.selection{stroke:gray;stroke-dasharray:4px;stroke-opacity:.5;fill:transparent}svg ::selection{background:0 0}svg ::-moz-selection{background:0 0}svg ::-webkit-selection{background:0 0}.btn-danger:focus,.btn-danger:hover,.btn-default:focus,.btn-default:hover,.btn-info:focus,.btn-info:hover,.btn-primary:focus,.btn-primary:hover,.btn-success:focus,.btn-success:hover,.btn-warning:focus,.btn-warning:hover{background-position:0 -15px}[animate-on-change]{transition:all 1s;-webkit-transition:all 1s}[animate-on-change].changed{background-color:#add8e6;transition:none;-webkit-transition:none}[animate-on-change].changedshut{background-color:#ffa07a;transition:none;-webkit-transition:none}.panel-heading .nav-justified.nav-pills li.active>a{background-color:#74a9d8!important}div[data-angular-treeview]{-moz-user-select:-moz-none;-khtml-user-select:none;-webkit-user-select:none;-ms-user-select:none;user-select:none;font-family:"Helvetica Neue",Helvetica,Arial,sans-serif;font-size:14px;font-weight:600;color:#fff;text-decoration:none;text-shadow:1px 1px #000}div[data-tree-model] ul{padding:5px;list-style:none;border:#778899;overflow:hidden}div[data-tree-model] li{position:relative;padding:0 0 0 20px;line-height:20px;margin-top:3px;border:#add8e6;border-radius:10px;box-shadow:2px 3px 5px rgba(0,0,0,.6),inset 1px 10px 300px 51px rgba(33,151,184,1)}div[data-tree-model] li .expanded{padding:1px 10px;background-image:url(../img/folder.png);background-repeat:no-repeat}div[data-tree-model] li .collapsed{padding:1px 10px;background-image:url(../img/folder-closed.png);background-repeat:no-repeat}div[data-tree-model] li .normal{padding:1px 10px;color:#000;background-image:url(../img/file.png);background-repeat:no-repeat}div[data-tree-model] li.selected{box-shadow:2px 3px 5px rgba(0,0,0,.6),inset 1px 10px 300px 51px #5cb85c!important}div[data-tree-model] span.selected{color:#fff!important;text-shadow:1px 1px #000!important;font-weight:700;padding:1px 5px}div[data-tree-model] li.changed{box-shadow:2px 3px 5px rgba(0,0,0,.6),inset 1px 10px 300px 51px rgba(250,250,210,1)}div[data-tree-model] span.changed{color:#000;text-shadow:1px 1px #fff;font-weight:700;padding:1px 5px}div[data-tree-model] span.loaded{text-decoration:underline;font-style:oblique}/*!
  * Bootstrap v3.3.6 (http://getbootstrap.com)
  * Copyright 2011-2015 Twitter, Inc.
Index: /branches/WebJobManager/HeuristicLab.Clients.Hive.WebJobManager/wwwroot/js/hubs/calendarhubber.js
===================================================================
--- /branches/WebJobManager/HeuristicLab.Clients.Hive.WebJobManager/wwwroot/js/hubs/calendarhubber.js	(revision 13804)
+++ /branches/WebJobManager/HeuristicLab.Clients.Hive.WebJobManager/wwwroot/js/hubs/calendarhubber.js	(revision 13805)
@@ -14,5 +14,6 @@
                vm.alertMessage = "No alerts";
                vm.currentcal = [];
-               $scope.permission = false;
+               $scope.permissionview = false;
+               $scope.resaddview = false;
                vm.selectedEventId = -1;
                vm.groups = [];
@@ -100,4 +101,5 @@
                    $scope.$watch("treeview.currentNode", function (newValue, oldValue) {
                        $scope.currentcal = [];
+                       $scope.resaddview = false;
                        $(".selected.ng-binding").addClass('loaded');
                        $scope.selectedEventId = -1;
@@ -112,11 +114,22 @@
                                $timeout(function () {
                                    refreshPermissions();
+                                   
                                    $scope.currentcal = $scope.treeview.currentNode.calendar;
                                }, 0);
 
                            }
-                       }
-
-                   });
+                           $scope.refreshAdds();
+                       }
+
+                   });
+               }
+               $scope.refreshAdds = function() {
+                   for (var i = 0; i < $scope.clients.length; i++) {
+                       $scope.clients[i].add = false;
+                       for (var j = 0; j < $scope.treeview.currentNode.children.length; j++) {
+                           if ($scope.clients[i].Id === $scope.treeview.currentNode.children[j].Id)
+                               $scope.clients[i].add = true;
+                       }
+                   }
                }
                function refreshPermissions() {
@@ -650,4 +663,21 @@
                };
 
+               $scope.menuchange = function (i) {
+                   switch(i) {
+                       case 0:
+                           $scope.permissionview = false;
+                           $scope.resaddview = false;
+                           break;
+                       case 1:
+                           $scope.permissionview = true;
+                           $scope.resaddview = false;
+                           break;
+                       case 2:
+                           $scope.permissionview = false;
+                           $scope.resaddview = true;
+                           break;
+                   }
+               }
+
 
 
Index: /branches/WebJobManager/HeuristicLab.Clients.Hive.WebJobManager/wwwroot/js/hubs/userinfohubber.js
===================================================================
--- /branches/WebJobManager/HeuristicLab.Clients.Hive.WebJobManager/wwwroot/js/hubs/userinfohubber.js	(revision 13804)
+++ /branches/WebJobManager/HeuristicLab.Clients.Hive.WebJobManager/wwwroot/js/hubs/userinfohubber.js	(revision 13805)
@@ -1,1 +1,1 @@
-function resetPass(a){hubber.server.resetPassword(a)}var hubber=$.connection.userInfoHub;$(function(){$.connection.hub.logging=!0;var a=document.getElementById("userId").innerHTML;console.log(a),$.connection.hub.qs={userid:a},$.connection.hub.start(),hubber.client.showNewPass=function(a){$("#inppassreset").html("<label class=' control-label' style='text-align:left'>New password: "+a+"</label>")}});
+function resetPass(a){hubber.server.resetPassword(a)}var hubber=$.connection.userInfoHub;$(function(){var a=document.getElementById("userId").innerHTML;console.log(a),$.connection.hub.qs={userid:a},$.connection.hub.start(),hubber.client.showNewPass=function(a){$("#inppassreset").html("<label class=' control-label' style='text-align:left'>An email has been sent to the user containing the new password</label>")}});
