Index: branches/HiveStatistics/sources/HeuristicLab.Services.WebApp.Statistics/3.3/HeuristicLab.Services.WebApp.Statistics-3.3.csproj
===================================================================
--- branches/HiveStatistics/sources/HeuristicLab.Services.WebApp.Statistics/3.3/HeuristicLab.Services.WebApp.Statistics-3.3.csproj	(revision 12551)
+++ branches/HiveStatistics/sources/HeuristicLab.Services.WebApp.Statistics/3.3/HeuristicLab.Services.WebApp.Statistics-3.3.csproj	(revision 12560)
@@ -82,4 +82,5 @@
       <SpecificVersion>False</SpecificVersion>
       <HintPath>..\..\packages\Newtonsoft.Json.7.0.1\lib\net45\Newtonsoft.Json.dll</HintPath>
+      <Private>False</Private>
     </Reference>
     <Reference Include="System" />
Index: branches/HiveStatistics/sources/HeuristicLab.Services.WebApp.Statistics/3.3/WebApi/DataTransfer/Exception.cs
===================================================================
--- branches/HiveStatistics/sources/HeuristicLab.Services.WebApp.Statistics/3.3/WebApi/DataTransfer/Exception.cs	(revision 12560)
+++ branches/HiveStatistics/sources/HeuristicLab.Services.WebApp.Statistics/3.3/WebApi/DataTransfer/Exception.cs	(revision 12560)
@@ -0,0 +1,15 @@
+﻿using System;
+
+namespace HeuristicLab.Services.WebApp.Statistics.WebApi.DataTransfer {
+  public class Exception {
+    public Guid TaskId { get; set; }
+    public Guid JobId { get; set; }
+    public string JobName { get; set; }
+    public Guid UserId { get; set; }
+    public string UserName { get; set; }
+    public Guid ClientId { get; set; }
+    public string ClientName { get; set; }
+    public DateTime Date { get; set; }
+    public string Details { get; set; }
+  }
+}
Index: branches/HiveStatistics/sources/HeuristicLab.Services.WebApp.Statistics/3.3/WebApi/DataTransfer/ExceptionPage.cs
===================================================================
--- branches/HiveStatistics/sources/HeuristicLab.Services.WebApp.Statistics/3.3/WebApi/DataTransfer/ExceptionPage.cs	(revision 12560)
+++ branches/HiveStatistics/sources/HeuristicLab.Services.WebApp.Statistics/3.3/WebApi/DataTransfer/ExceptionPage.cs	(revision 12560)
@@ -0,0 +1,9 @@
+﻿
+using System.Collections.Generic;
+
+namespace HeuristicLab.Services.WebApp.Statistics.WebApi.DataTransfer {
+  public class ExceptionPage {
+    public int TotalExceptions { get; set; }
+    public IEnumerable<Exception> Exceptions { get; set; }
+  }
+}
Index: branches/HiveStatistics/sources/HeuristicLab.Services.WebApp.Statistics/3.3/WebApi/DataTransfer/UserDetails.cs
===================================================================
--- branches/HiveStatistics/sources/HeuristicLab.Services.WebApp.Statistics/3.3/WebApi/DataTransfer/UserDetails.cs	(revision 12560)
+++ branches/HiveStatistics/sources/HeuristicLab.Services.WebApp.Statistics/3.3/WebApi/DataTransfer/UserDetails.cs	(revision 12560)
@@ -0,0 +1,31 @@
+﻿#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2015 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ *
+ * This file is part of HeuristicLab.
+ *
+ * HeuristicLab is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * HeuristicLab is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
+ */
+#endregion
+
+using System;
+using System.Collections.Generic;
+
+namespace HeuristicLab.Services.WebApp.Statistics.WebApi.DataTransfer {
+  public class UserDetails {
+    public Guid Id { get; set; }
+    public string Name { get; set; }
+    public IEnumerable<TaskStateCount> TasksStates { get; set; }
+  }
+}
Index: branches/HiveStatistics/sources/HeuristicLab.Services.WebApp.Statistics/3.3/WebApi/ExceptionController.cs
===================================================================
--- branches/HiveStatistics/sources/HeuristicLab.Services.WebApp.Statistics/3.3/WebApi/ExceptionController.cs	(revision 12560)
+++ branches/HiveStatistics/sources/HeuristicLab.Services.WebApp.Statistics/3.3/WebApi/ExceptionController.cs	(revision 12560)
@@ -0,0 +1,49 @@
+﻿
+using System;
+using System.Linq;
+using System.Web.Http;
+using HeuristicLab.Services.Hive;
+using HeuristicLab.Services.Hive.DataAccess.Interfaces;
+using DT = HeuristicLab.Services.WebApp.Statistics.WebApi.DataTransfer;
+
+namespace HeuristicLab.Services.WebApp.Statistics.WebApi {
+  [Authorize(Roles = HiveRoles.Administrator)]
+  public class ExceptionController : ApiController {
+    private IPersistenceManager PersistenceManager {
+      get { return ServiceLocator.Instance.PersistenceManager; }
+    }
+
+    public DT.ExceptionPage GetExceptions(int page, int size) {
+      using (var pm = PersistenceManager) {
+        var dimClientDao = pm.DimClientDao;
+        var dimJobDao = pm.DimJobDao;
+        var factTaskDao = pm.FactTaskDao;
+        var tasks = factTaskDao.GetTasksWithException();
+        return pm.UseTransaction(() => new DT.ExceptionPage {
+          TotalExceptions = tasks.Count(),
+          Exceptions = (from factTask in tasks
+                        join dimJob in dimJobDao.GetAll() on factTask.JobId equals dimJob.JobId
+                        join dimClient in dimClientDao.GetAll() on factTask.LastClientId equals
+                          dimClient.Id into taskClientJoin
+                        from a in taskClientJoin.DefaultIfEmpty()
+                        let endTime = factTask.EndTime ?? DateTime.Now
+                        select new DT.Exception {
+                          TaskId = factTask.TaskId,
+                          JobId = factTask.JobId,
+                          JobName = dimJob.JobName,
+                          UserId = dimJob.UserId,
+                          UserName = dimJob.UserName,
+                          ClientId = factTask.LastClientId ?? default(Guid),
+                          ClientName = a != null ? a.Name : string.Empty,
+                          Date = endTime,
+                          Details = factTask.Exception
+                        })
+                        .OrderByDescending(x => x.Date)
+                        .Skip((page - 1) * size)
+                        .Take(size)
+                        .ToList()
+        });
+      }
+    }
+  }
+}
Index: branches/HiveStatistics/sources/HeuristicLab.Services.WebApp.Statistics/3.3/WebApp/exceptions/exceptionDetailsDialog.cshtml
===================================================================
--- branches/HiveStatistics/sources/HeuristicLab.Services.WebApp.Statistics/3.3/WebApp/exceptions/exceptionDetailsDialog.cshtml	(revision 12560)
+++ branches/HiveStatistics/sources/HeuristicLab.Services.WebApp.Statistics/3.3/WebApp/exceptions/exceptionDetailsDialog.cshtml	(revision 12560)
@@ -0,0 +1,9 @@
+﻿<div class="modal-header">
+    <button type="button" ng-click="close()" class="close" data-dismiss="modal" aria-label="Close"><span aria-hidden="true">&times;</span></button>
+    <h4 class="modal-title">Exception Details</h4>
+</div>
+<div class="modal-body">
+    <div style="overflow:auto;">
+        <p style="word-wrap: break-word;">{{message}}</p>
+    </div>
+</div>
Index: branches/HiveStatistics/sources/HeuristicLab.Services.WebApp.Statistics/3.3/WebApp/exceptions/exceptionDetailsDialogCtrl.js
===================================================================
--- branches/HiveStatistics/sources/HeuristicLab.Services.WebApp.Statistics/3.3/WebApp/exceptions/exceptionDetailsDialogCtrl.js	(revision 12560)
+++ branches/HiveStatistics/sources/HeuristicLab.Services.WebApp.Statistics/3.3/WebApp/exceptions/exceptionDetailsDialogCtrl.js	(revision 12560)
@@ -0,0 +1,11 @@
+﻿(function () {
+    var module = appStatisticsPlugin.getAngularModule();
+    module.controller('app.statistics.exceptionDetailsDialogCtrl',
+        ['$scope', '$modalInstance', 'message', function ($scope, $modalInstance, message) {
+            $scope.message = message;
+            $scope.close = function () {
+                $modalInstance.dismiss('cancel');
+            };
+        }]
+    );
+})();
Index: branches/HiveStatistics/sources/HeuristicLab.Services.WebApp.Statistics/3.3/WebApp/exceptions/exceptions.cshtml
===================================================================
--- branches/HiveStatistics/sources/HeuristicLab.Services.WebApp.Statistics/3.3/WebApp/exceptions/exceptions.cshtml	(revision 12560)
+++ branches/HiveStatistics/sources/HeuristicLab.Services.WebApp.Statistics/3.3/WebApp/exceptions/exceptions.cshtml	(revision 12560)
@@ -0,0 +1,66 @@
+﻿@using HeuristicLab.Services.Access.DataTransfer
+@using HeuristicLab.Services.Hive
+@if (Request.IsAuthenticated && User.IsInRole(HiveRoles.Administrator)) {
+<header class="view-header">
+    <ul class="nav nav-list nav-list-topbar pull-left">
+        <li>
+            <a ng-href="#/statistics/jobs">Jobs</a>
+        </li>
+        <li>
+            <a ng-href="#/statistics/users">Users</a>
+        </li>
+        <li>
+            <a ng-href="#/statistics/clients">Clients</a>
+        </li>
+        <li>
+            <a ng-href="#/statistics/groups">Groups</a>
+        </li>
+        <li class="active">
+            <a ng-href="#/statistics/exceptions">Exceptions</a>
+        </li>
+    </ul>
+</header>
+
+<div class="default-view-container">
+    <div class="row">
+        <div class="col-lg-12">
+            <div class="panel panel-default">
+                <div class="panel-heading">
+                    <h3 class="panel-title">Groups</h3>
+                </div>
+                <div class="panel-body">
+                    <table class="table table-hover table-condensed">
+                        <thead>
+                        <tr>
+                            <th>#</th>
+                            <th>Job</th>
+                            <th>Task</th>
+                            <th>User</th>
+                            <th>Client</th>
+                            <th>Date</th>
+                            <th></th>
+                        </tr>
+                        </thead>
+                        <tr ng-repeat="exception in exceptionPage.Exceptions">
+                            <td>{{($index + 1)+((curExceptionsPage-1)*(exceptionsPageSize))}}</td>
+                            <td><a ng-href="#/statistics/jobs/{{exception.JobId}}">{{exception.JobName}}</a></td>
+                            <td><a ng-href="#/statistics/tasks/{{exception.TaskId}}">{{exception.TaskId}}</a></td>
+                            <td><a ng-href="#/statistics/users/{{exception.UserId}}">{{exception.UserName}}</a></td>
+                            <td><a ng-href="#/statistics/clients/{{exception.ClientId}}">{{exception.ClientName}}</a></td>
+                            <td>{{exception.Date | toDate}}</td>
+                            <td><a class="cursor-pointer" ng-click="openDialog(exception.Details)">Details</a></td>
+                        </tr>
+                        <tr ng-hide="exceptionPage.Exceptions.length">
+                            <td colspan="7" class="text-center">No exceptions found!</td>
+                        </tr>
+                    </table>
+                    <div class="row text-center" ng-show="exceptionPage.TotalExceptions > exceptionPage.Exceptions.length">
+                        <pagination max-size="10" total-items="exceptionPage.TotalExceptions" ng-model="curExceptionsPage" ng-change="changeExceptionsPage()"
+                                    items-per-page="exceptionsPageSize" boundary-links="true" rotate="false" num-pages="numPages"></pagination>
+                    </div>
+                </div>
+            </div>
+        </div>
+    </div>
+</div>
+}
Index: branches/HiveStatistics/sources/HeuristicLab.Services.WebApp.Statistics/3.3/WebApp/exceptions/exceptionsCtrl.js
===================================================================
--- branches/HiveStatistics/sources/HeuristicLab.Services.WebApp.Statistics/3.3/WebApp/exceptions/exceptionsCtrl.js	(revision 12560)
+++ branches/HiveStatistics/sources/HeuristicLab.Services.WebApp.Statistics/3.3/WebApp/exceptions/exceptionsCtrl.js	(revision 12560)
@@ -0,0 +1,49 @@
+﻿(function () {
+    var module = appStatisticsPlugin.getAngularModule();
+    module.controller('app.statistics.exceptionsCtrl',
+        ['$scope', '$interval', '$modal', 'app.statistics.exceptionService',
+            function ($scope, $interval, $modal, exceptionService) {
+                $scope.interval = defaultPageUpdateInterval;
+                $scope.curExceptionsPage = 1;
+                $scope.exceptionsPageSize = 20;
+
+                var getExceptions = function () {
+                    exceptionService.getExceptions({ page: $scope.curExceptionsPage, size: $scope.exceptionsPageSize },
+                        function (exceptionPage) {
+                            $scope.exceptionPage = exceptionPage;
+                        }
+                    );
+                };
+
+                $scope.changeExceptionsPage = function () {
+                    update();
+                };
+
+                var update = function () {
+                    getExceptions();
+                };
+
+                $scope.openDialog = function (message) {
+                    $scope.message = message;
+                    $modal.open({
+                        templateUrl: 'plugin=statistics&view=WebApp/exceptions/exceptionDetailsDialog.cshtml',
+                        controller: 'app.statistics.exceptionDetailsDialogCtrl',
+                        windowClass: 'app-modal-window',
+                        resolve: {
+                            message: function () {
+                                return $scope.message;
+                            }
+                        }
+                    });
+                };
+
+                $scope.updateInterval = $interval(update, $scope.interval);
+                var cancelInterval = $scope.$on('$locationChangeSuccess', function () {
+                    $interval.cancel($scope.updateInterval);
+                    cancelInterval();
+                });
+                update();
+            }
+        ]
+    );
+})();
Index: branches/HiveStatistics/sources/HeuristicLab.Services.WebApp.Statistics/3.3/WebApp/services/exceptionService.js
===================================================================
--- branches/HiveStatistics/sources/HeuristicLab.Services.WebApp.Statistics/3.3/WebApp/services/exceptionService.js	(revision 12560)
+++ branches/HiveStatistics/sources/HeuristicLab.Services.WebApp.Statistics/3.3/WebApp/services/exceptionService.js	(revision 12560)
@@ -0,0 +1,11 @@
+﻿(function () {
+    var module = appStatisticsPlugin.getAngularModule();
+    var apiUrl = 'api/Statistics/Exception/';
+    module.factory('app.statistics.exceptionService',
+        ['$resource', function ($resource) {
+            return $resource(apiUrl + ':action', { page: '@page', size: '@size'}, {
+                getExceptions: { method: 'GET', params: { action: 'GetExceptions' } }
+            });
+        }]
+    );
+})();
Index: branches/HiveStatistics/sources/HeuristicLab.Services.WebApp.Statistics/3.3/WebApp/services/groupService.js
===================================================================
--- branches/HiveStatistics/sources/HeuristicLab.Services.WebApp.Statistics/3.3/WebApp/services/groupService.js	(revision 12560)
+++ branches/HiveStatistics/sources/HeuristicLab.Services.WebApp.Statistics/3.3/WebApp/services/groupService.js	(revision 12560)
@@ -0,0 +1,13 @@
+﻿(function () {
+    var module = appStatisticsPlugin.getAngularModule();
+    var apiUrl = 'api/Statistics/Group/';
+    module.factory('app.statistics.groupService',
+        ['$resource', function ($resource) {
+            return $resource(apiUrl + ':action', { id: '@id', page: '@page', size: '@size', start: '@start', end: '@end' }, {
+                getGroupDetails: { method: 'GET', params: { action: 'GetGroupDetails' } },
+                getGroups: { method: 'GET', params: { action: 'GetGroups' } },
+                getGroupHistory: { method: 'GET', params: { action: 'GetGroupHistory' }, isArray: true }
+            });
+        }]
+    );
+})();
Index: branches/HiveStatistics/sources/HeuristicLab.Services.WebApp.Statistics/3.3/statistics.js
===================================================================
--- branches/HiveStatistics/sources/HeuristicLab.Services.WebApp.Statistics/3.3/statistics.js	(revision 12551)
+++ branches/HiveStatistics/sources/HeuristicLab.Services.WebApp.Statistics/3.3/statistics.js	(revision 12560)
@@ -39,5 +39,5 @@
     ];
     var menu = app.getMenu();
-    var section = menu.getSection('Menü', 1);
+    var section = menu.getSection('Menu', 1);
     section.addEntry({
         name: 'Statistics',
