Index: branches/HiveProjectManagement/HeuristicLab.Services.Hive/3.3/HiveStatisticsGenerator.cs
===================================================================
--- branches/HiveProjectManagement/HeuristicLab.Services.Hive/3.3/HiveStatisticsGenerator.cs	(revision 15715)
+++ branches/HiveProjectManagement/HeuristicLab.Services.Hive/3.3/HiveStatisticsGenerator.cs	(revision 15716)
@@ -40,4 +40,5 @@
         pm.UseTransaction(() => {
           UpdateDimProjectTable(pm);
+          pm.SubmitChanges();
         });
 
@@ -59,4 +60,5 @@
           pm.UseTransaction(() => {
             UpdateFactClientInfoTable(time, pm);
+            pm.SubmitChanges();
             UpdateFactProjectInfoTable(time, pm);
             pm.SubmitChanges();
@@ -64,5 +66,5 @@
 
           pm.UseTransaction(() => {
-            UpdateTaskFactsTable(pm);
+            UpdateFactTaskTable(pm);
             try {
               pm.SubmitChanges();
@@ -150,10 +152,10 @@
       }));
 
-      // if a project's parent has changed expire entry in DimProject and create a new entry
-      // else perform "normal" update
+      // expire project if its parent has changed and create a new entry
+      // otherwise perform "normal" update
       foreach (var dimP in onlineProjects) {
         var p = projects.Where(x => x.ProjectId == dimP.ProjectId).SingleOrDefault();
         if (p != null) {
-          if (dimP.ParentProjectId != p.ParentProjectId) {
+          if (dimP.ParentProjectId == null ? p.ParentProjectId != null : dimP.ParentProjectId != p.ParentProjectId) { // or: (!object.Equals(dimP.ParentProjectId, p.ParentProjectId))
             dimP.DateExpired = DateTime.Now;
             dimProjectDao.Save(new DimProject {
@@ -256,56 +258,106 @@
     }
 
-    // (1) for new slaves (not yet reported in Table DimClients) ...
-    // and modified slaves (name or parent resource changed) a new DimClient-entry is created
-    // (2) for already reported removed and modifid clients the expiration date is set
     private void UpdateDimClientsTable(PersistenceManager pm) {
       var dimClientDao = pm.DimClientDao;
-      var slaveDao = pm.SlaveDao;
-      var slaves = slaveDao.GetAll();
-      var recentlyAddedClients = dimClientDao.GetActiveClients();
-      var slaveIds = slaves.Select(x => x.ResourceId);
-
-      var removedClientIds = recentlyAddedClients
-        .Where(x => !slaveIds.Contains(x.ResourceId))
-        .Select(x => x.Id);
-      var modifiedClients =
-        from slave in slaves
-        join client in recentlyAddedClients on slave.ResourceId equals client.ResourceId
-        where (slave.Name != client.Name
-               || slave.ParentResourceId == null && client.ResourceGroupId != null // because both can be null and null comparison
-               || slave.ParentResourceId != null && client.ResourceGroupId == null // does return no entry on the sql server
-               || slave.ParentResourceId != client.ResourceGroupId
-               || ((slave.ParentResource != null) && slave.ParentResource.ParentResourceId != client.ResourceGroup2Id))
-        select new {
-          SlaveId = slave.ResourceId,
-          ClientId = client.Id
-        };
-      var clientIds = dimClientDao.GetActiveClients().Select(x => x.ResourceId);
-      var modifiedClientIds = modifiedClients.Select(x => x.SlaveId);
-      var newClients = slaves
-        .Where(x => !clientIds.Contains(x.ResourceId)
-                    || modifiedClientIds.Contains(x.ResourceId))
-        .Select(x => new {
-          x.ResourceId,
-          x.Name,
-          ResourceGroupId = x.ParentResourceId,
-          GroupName = x.ParentResource != null ? x.ParentResource.Name : null,
-          ResourceGroup2Id = x.ParentResource != null ? x.ParentResource.ParentResourceId : null,
-          GroupName2 = x.ParentResource != null ? x.ParentResource.ParentResource != null ? x.ParentResource.ParentResource.Name : null : null
-        })
-        .ToList();
-
-      var clientsToUpdate = removedClientIds.Union(modifiedClients.Select(x => x.ClientId));
-      dimClientDao.UpdateExpirationTime(clientsToUpdate, DateTime.Now);
-      dimClientDao.Save(newClients.Select(x => new DimClient {
+      var resourceDao = pm.ResourceDao;
+
+      var resources = resourceDao.GetAll().ToList();
+      var dimClients = dimClientDao.GetAllOnlineClients().ToList();
+
+      var onlineClients = dimClients.Where(x => resources.Select(y => y.ResourceId).Contains(x.ResourceId));
+      var addedResources = resources.Where(x => !dimClients.Select(y => y.ResourceId).Contains(x.ResourceId));
+      var removedResources = dimClients.Where(x => !resources.Select(y => y.ResourceId).Contains(x.ResourceId));
+
+      // set expiration time of removed resources
+      foreach(var r in removedResources) {
+        r.DateExpired = DateTime.Now;
+      }
+
+      // add new resources
+      dimClientDao.Save(addedResources.Select(x => new DimClient {
         ResourceId = x.ResourceId,
+        ParentResourceId = x.ParentResourceId,
         Name = x.Name,
-        ExpirationTime = null,
-        ResourceGroupId = x.ResourceGroupId,
-        GroupName = x.GroupName,
-        ResourceGroup2Id = x.ResourceGroup2Id,
-        GroupName2 = x.GroupName2
+        ResourceType = x.ResourceType,
+        DateCreated = DateTime.Now,
+        DateExpired = null
       }));
-    }
+
+      // expire client if its parent has changed and create a new entry
+      // otherwise perform "normal" update
+      foreach(var dimc in onlineClients) {
+        var r = resources.Where(x => x.ResourceId == dimc.ResourceId).SingleOrDefault();
+        if(r != null) {
+          if(dimc.ParentResourceId == null ? r.ParentResourceId != null : dimc.ParentResourceId != r.ParentResourceId) {
+            var now = DateTime.Now;
+            dimc.DateExpired = now;
+            dimClientDao.Save(new DimClient {
+              ResourceId = r.ResourceId,
+              ParentResourceId = r.ParentResourceId,
+              Name = r.Name,
+              ResourceType = r.ResourceType,
+              DateCreated = now,
+              DateExpired = null
+            });
+          } else {
+            dimc.Name = r.Name;
+          }
+        }
+      }
+    }
+
+    //// (1) for new slaves (not yet reported in Table DimClients) ...
+    //// and modified slaves (name or parent resource changed) a new DimClient-entry is created
+    //// (2) for already reported removed and modifid clients the expiration date is set
+    //private void UpdateDimClientsTableOld(PersistenceManager pm) {
+    //  var dimClientDao = pm.DimClientDao;
+    //  var slaveDao = pm.SlaveDao;
+    //  var slaves = slaveDao.GetAll();
+    //  var recentlyAddedClients = dimClientDao.GetAllOnlineClients();
+    //  var slaveIds = slaves.Select(x => x.ResourceId);
+
+    //  var removedClientIds = recentlyAddedClients
+    //    .Where(x => !slaveIds.Contains(x.ResourceId))
+    //    .Select(x => x.Id);
+    //  var modifiedClients =
+    //    from slave in slaves
+    //    join client in recentlyAddedClients on slave.ResourceId equals client.ResourceId
+    //    where (slave.Name != client.Name
+    //           || slave.ParentResourceId == null && client.ResourceGroupId != null // because both can be null and null comparison
+    //           || slave.ParentResourceId != null && client.ResourceGroupId == null // does return no entry on the sql server
+    //           || slave.ParentResourceId != client.ResourceGroupId
+    //           || ((slave.ParentResource != null) && slave.ParentResource.ParentResourceId != client.ResourceGroup2Id))
+    //    select new {
+    //      SlaveId = slave.ResourceId,
+    //      ClientId = client.Id
+    //    };
+    //  var clientIds = dimClientDao.GetAllOnlineClients().Select(x => x.ResourceId);
+    //  var modifiedClientIds = modifiedClients.Select(x => x.SlaveId);
+    //  var newClients = slaves
+    //    .Where(x => !clientIds.Contains(x.ResourceId)
+    //                || modifiedClientIds.Contains(x.ResourceId))
+    //    .Select(x => new {
+    //      x.ResourceId,
+    //      x.Name,
+    //      ResourceGroupId = x.ParentResourceId,
+    //      GroupName = x.ParentResource != null ? x.ParentResource.Name : null,
+    //      ResourceGroup2Id = x.ParentResource != null ? x.ParentResource.ParentResourceId : null,
+    //      GroupName2 = x.ParentResource != null ? x.ParentResource.ParentResource != null ? x.ParentResource.ParentResource.Name : null : null
+    //    })
+    //    .ToList();
+
+    //  var clientsToUpdate = removedClientIds.Union(modifiedClients.Select(x => x.ClientId));
+    //  dimClientDao.UpdateExpirationTime(clientsToUpdate, DateTime.Now);
+    //  dimClientDao.Save(newClients.Select(x => new DimClient {
+    //    ResourceId = x.ResourceId,
+    //    Name = x.Name,
+    //    ExpirationTime = null,
+    //    ResourceGroupId = x.ResourceGroupId,
+    //    GroupName = x.GroupName,
+    //    ResourceGroup2Id = x.ResourceGroup2Id,
+    //    GroupName2 = x.GroupName2
+    //  }));
+    //}
+
 
     private void UpdateFactClientInfoTable(DimTime newTime, PersistenceManager pm) {
@@ -316,5 +368,5 @@
       var newRawFactInfos =
         from s in slaveDao.GetAll()
-        join c in dimClientDao.GetActiveClients() on s.ResourceId equals c.ResourceId
+        join c in dimClientDao.GetAllOnlineSlaves() on s.ResourceId equals c.ResourceId
         join lcf in factClientInfoDao.GetLastUpdateTimestamps() on c.ResourceId equals lcf.ResourceId into joinCf
         from cf in joinCf.DefaultIfEmpty()
@@ -379,5 +431,5 @@
     }
 
-    private void UpdateTaskFactsTable(PersistenceManager pm) {
+    private void UpdateFactTaskTable(PersistenceManager pm) {
       var factTaskDao = pm.FactTaskDao;
       var taskDao = pm.TaskDao;
@@ -392,5 +444,5 @@
 
       // query several properties for all new and not finished tasks
-      // in order to use them later eitheir
+      // in order to use them later either...
       // (1) to update the fact task entry of not finished tasks
       // (2) to insert a new fact task entry for new tasks
@@ -403,5 +455,5 @@
          join lastFactTask in notFinishedFactTasks on task.TaskId equals lastFactTask.TaskId into lastFactPerTask
          from lastFact in lastFactPerTask.DefaultIfEmpty()
-         join client in dimClientDao.GetActiveClients() on lastSlaveId equals client.ResourceId into clientsPerSlaveId
+         join client in dimClientDao.GetAllOnlineClients() on lastSlaveId equals client.ResourceId into clientsPerSlaveId
          from client in clientsPerSlaveId.DefaultIfEmpty()
          select new {
