Index: /trunk/HeuristicLab.Clients.Hive.Administrator/3.3/Views/ProjectJobsView.Designer.cs
===================================================================
--- /trunk/HeuristicLab.Clients.Hive.Administrator/3.3/Views/ProjectJobsView.Designer.cs	(revision 16207)
+++ /trunk/HeuristicLab.Clients.Hive.Administrator/3.3/Views/ProjectJobsView.Designer.cs	(revision 16208)
@@ -76,5 +76,5 @@
       this.removeButton.Size = new System.Drawing.Size(24, 24);
       this.removeButton.TabIndex = 2;
-      this.toolTip.SetToolTip(this.removeButton, "Delete job(s)");
+      this.toolTip.SetToolTip(this.removeButton, "Remove job(s)");
       this.removeButton.UseVisualStyleBackColor = true;
       this.removeButton.Click += new System.EventHandler(this.removeButton_Click);
@@ -82,7 +82,7 @@
       // startButton
       // 
-      this.startButton.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left)));
+      this.startButton.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left)));
       this.startButton.Image = HeuristicLab.Common.Resources.VSImageLibrary.Play;
-      this.startButton.Location = new System.Drawing.Point(0, 564);
+      this.startButton.Location = new System.Drawing.Point(63, 3);
       this.startButton.Name = "startButton";
       this.startButton.Size = new System.Drawing.Size(24, 24);
@@ -94,8 +94,8 @@
       // pauseButton
       // 
-      this.pauseButton.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left)));
+      this.pauseButton.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left)));
       this.pauseButton.Enabled = false;
       this.pauseButton.Image = HeuristicLab.Common.Resources.VSImageLibrary.Pause;
-      this.pauseButton.Location = new System.Drawing.Point(30, 564);
+      this.pauseButton.Location = new System.Drawing.Point(93, 3);
       this.pauseButton.Name = "pauseButton";
       this.pauseButton.Size = new System.Drawing.Size(24, 24);
@@ -107,7 +107,7 @@
       // stopButton
       // 
-      this.stopButton.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left)));
+      this.stopButton.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left)));
       this.stopButton.Image = HeuristicLab.Common.Resources.VSImageLibrary.Stop;
-      this.stopButton.Location = new System.Drawing.Point(60, 564);
+      this.stopButton.Location = new System.Drawing.Point(123, 3);
       this.stopButton.Name = "stopButton";
       this.stopButton.Size = new System.Drawing.Size(24, 24);
@@ -139,4 +139,7 @@
       this.Controls.Add(this.refreshButton);
       this.Controls.Add(this.removeButton);
+      this.Controls.Add(this.startButton);
+      this.Controls.Add(this.pauseButton);
+      this.Controls.Add(this.stopButton);
       this.Name = "ProjectJobsView";
       this.Size = new System.Drawing.Size(510, 385);
Index: /trunk/HeuristicLab.Clients.Hive.Administrator/3.3/Views/ProjectJobsView.cs
===================================================================
--- /trunk/HeuristicLab.Clients.Hive.Administrator/3.3/Views/ProjectJobsView.cs	(revision 16207)
+++ /trunk/HeuristicLab.Clients.Hive.Administrator/3.3/Views/ProjectJobsView.cs	(revision 16208)
@@ -24,4 +24,5 @@
 using System.Drawing;
 using System.Linq;
+using System.Threading.Tasks;
 using System.Windows.Forms;
 using HeuristicLab.MainForm;
@@ -30,4 +31,5 @@
 using HeuristicLab.Data;
 using HeuristicLab.Clients.Hive.Views;
+using HeuristicLab.Core;
 
 namespace HeuristicLab.Clients.Hive.Administrator.Views {
@@ -41,9 +43,9 @@
     private const string JOB_DATECREATED = "Date Created";
     private const string JOB_STATE = "State";
+    private const string JOB_EXECUTIONSTATE = "Execution State";
     private const string JOB_DESCRIPTION = "Description";
     private const string JOB_TASKCOUNT = "Tasks";
     private const string JOB_CALCULATINGTASKCOUNT = "Calculating";
     private const string JOB_FINISHEDTASKCOUNT = "Finished";
-
 
     private readonly Color onlineStatusColor = Color.FromArgb(255, 189, 249, 143); // #bdf98f
@@ -53,4 +55,13 @@
     private readonly Color deletionPendingStatusColor2 = Color.FromArgb(255, 249, 149, 143); // #f9958f
 
+    private IProgress progress;
+    public IProgress Progress {
+      get { return progress; }
+      set {
+        this.progress = value;
+        OnIsProgressingChanged();
+      }
+    }
+
     public new Project Content {
       get { return (Project)base.Content; }
@@ -60,18 +71,23 @@
     public ProjectJobsView() {
       InitializeComponent();
-
-      removeButton.Enabled = false;
+      progress = new Progress();
+
+      removeButton.Enabled = false;      
+    }
+
+    protected override void RegisterContentEvents() {
+      base.RegisterContentEvents();
       matrixView.DataGridView.SelectionChanged += DataGridView_SelectionChanged;
+      MainFormManager.GetMainForm<HeuristicLab.MainForm.WindowsForms.MainForm>().AddOperationProgressToView(this, progress);
+    }
+
+    protected override void DeregisterContentEvents() {
+      matrixView.DataGridView.SelectionChanged -= DataGridView_SelectionChanged;
+      MainFormManager.GetMainForm<HeuristicLab.MainForm.WindowsForms.MainForm>().RemoveOperationProgressFromView(this, false);
+      base.DeregisterContentEvents();
     }
 
     private void DataGridView_SelectionChanged(object sender, EventArgs e) {
-      if (matrixView.DataGridView.SelectedRows == null || matrixView.DataGridView.SelectedRows.Count == 0) return;
-
-      bool anyDeletable = false;
-      foreach (DataGridViewRow r in matrixView.DataGridView.SelectedRows) {
-        if (((string)r.Cells[0].Value) == JobState.Online.ToString()) anyDeletable = true;
-      }
-
-      removeButton.Enabled = anyDeletable;
+      SetEnabledStateOfControls();
     }
 
@@ -81,13 +97,37 @@
       removeButton.Enabled = false;
       UpdateJobs();
-    }
+      SetEnabledStateOfControls();
+    }
+
     protected override void SetEnabledStateOfControls() {
       base.SetEnabledStateOfControls();
       bool enabled = Content != null && !Locked && !ReadOnly;
 
-      refreshButton.Enabled = enabled;
-      removeButton.Enabled = false;
       matrixView.Enabled = enabled;
-    }
+
+      // Buttons (start/resume, pause, stop, remove)
+      refreshButton.Enabled = startButton.Enabled = pauseButton.Enabled = stopButton.Enabled = removeButton.Enabled = false;
+
+      if (enabled && progress.ProgressState != ProgressState.Started) {
+        var jobs = GetSelectedJobs().ToList();
+        if (jobs.Any()) {
+
+          // TODO: include isControllable?!
+          startButton.Enabled = jobs.All(x =>
+            !x.IsProgressing && x.HiveTasks != null && x.HiveTasks.Count > 0
+            && x.Job.ProjectId != null && x.Job.ProjectId != Guid.Empty && x.Job.ResourceIds != null && x.Job.ResourceIds.Any()
+            && (x.ExecutionState == ExecutionState.Prepared || x.ExecutionState == ExecutionState.Paused));
+          pauseButton.Enabled = jobs.All(x => !x.IsProgressing && x.ExecutionState == ExecutionState.Started);
+          stopButton.Enabled = jobs.All(x => !x.IsProgressing && (x.ExecutionState == ExecutionState.Started || x.ExecutionState == ExecutionState.Paused));
+          removeButton.Enabled = jobs.All(x => !x.IsProgressing && x.Job.State == JobState.Online);
+        }
+      }
+
+      // refresh Button
+      if (Content != null && !Locked && progress.ProgressState != ProgressState.Started) {
+        refreshButton.Enabled = true;
+      }
+    }
+
     #endregion Overrides
 
@@ -98,58 +138,164 @@
 
     private void refreshButton_Click(object sender, EventArgs e) {
-      RefreshJobs();
-    }
-
-    private async void removeButton_Click(object sender, EventArgs e) {
-      if (matrixView.DataGridView.SelectedRows == null || matrixView.DataGridView.SelectedRows.Count == 0) return;
-
-      var jobNamesToDelete = new List<string>();
-      var jobIdsToDelete = new List<Guid>();
-      foreach (DataGridViewRow r in matrixView.DataGridView.SelectedRows) {
-        if(((string)r.Cells[0].Value) == JobState.Online.ToString()) {
-          jobNamesToDelete.Add(" - " + ((string)r.Cells[3].Value));
-          jobIdsToDelete.Add(Guid.Parse((string)r.Cells[8].Value));
-        }
-      }
-
-      if(jobIdsToDelete.Any()) {
+      var task = System.Threading.Tasks.Task.Factory.StartNew(RefreshJobsAsync);
+      progress.Start("Refreshing jobs...");
+      SetEnabledStateOfControls();
+
+      task.ContinueWith((t) => {
+        matrixView.DataGridView.ClearSelection();
+      });
+    }
+
+    private void removeButton_Click(object sender, EventArgs e) {
+      var jobs = GetSelectedJobs();
+
+      if (jobs.Any()) {
         var result = MessageBox.Show("Do you really want to remove following job(s):\n\n"
-          + String.Join("\n", jobNamesToDelete),
+                                     + String.Join("\n", jobs.Select(x => x.Job.Name)),
           "HeuristicLab Hive Administrator",
           MessageBoxButtons.YesNo,
           MessageBoxIcon.Question);
 
+        if (result == DialogResult.Yes) {          
+          var task = System.Threading.Tasks.Task.Factory.StartNew(RemoveJobsAsync, jobs);
+          progress.Start();
+          SetEnabledStateOfControls();
+
+          task.ContinueWith((t) => {
+            matrixView.DataGridView.ClearSelection();
+            RefreshJobs();
+            progress.Finish();
+          }, TaskContinuationOptions.NotOnFaulted);
+
+          task.ContinueWith((t) => {
+            matrixView.DataGridView.ClearSelection();
+            RefreshJobs();
+            progress.Finish();
+            MessageBox.Show("An error occured removing the job(s). " + t.Exception.Message, "HeuristicLab Hive Administrator", MessageBoxButtons.OK, MessageBoxIcon.Error);
+          }, TaskContinuationOptions.OnlyOnFaulted);
+        }
+      }
+    }
+
+    private void startButton_Click(object sender, EventArgs e) {
+      var jobs = GetSelectedJobs();
+
+      if (jobs.Any()) {
+        var result = MessageBox.Show("Do you really want to resume following job(s):\n\n"
+                                     + String.Join("\n", jobs.Select(x => x.Job.Name)),
+          "HeuristicLab Hive Administrator",
+          MessageBoxButtons.YesNo,
+          MessageBoxIcon.Question);
+
         if (result == DialogResult.Yes) {
-          await SecurityExceptionUtil.TryAsyncAndReportSecurityExceptions(
-            action: () => {
-              DeleteJobs(jobIdsToDelete);
-            },
-            finallyCallback: () => {
-              matrixView.DataGridView.ClearSelection();
-              removeButton.Enabled = false;
-              RefreshJobs();
-            });
-        }
-      } 
-    }
-
-    private async void startButton_Click(object sender, EventArgs e) {
-      throw new NotImplementedException();
-    }
-
-    private async void pauseButton_Click(object sender, EventArgs e) {
-      throw new NotImplementedException();
-    }
-
-    private async void stopButton_Click(object sender, EventArgs e) {
-      throw new NotImplementedException();
-    }
-
+          var task = System.Threading.Tasks.Task.Factory.StartNew(ResumeJobsAsync, jobs);
+          progress.Start();
+          SetEnabledStateOfControls();
+
+          task.ContinueWith((t) => {
+            matrixView.DataGridView.ClearSelection();
+            RefreshJobs();
+            progress.Finish();
+          });
+
+          task.ContinueWith((t) => {
+            matrixView.DataGridView.ClearSelection();
+            RefreshJobs();
+            progress.Finish();
+            MessageBox.Show("An error occured resuming the job(s).", "HeuristicLab Hive Administrator", MessageBoxButtons.OK, MessageBoxIcon.Error);
+          }, TaskContinuationOptions.OnlyOnFaulted);
+        }
+      }
+    }
+
+    private void pauseButton_Click(object sender, EventArgs e) {
+      var jobs = GetSelectedJobs();
+
+      if (jobs.Any()) {
+        var result = MessageBox.Show("Do you really want to pause following job(s):\n\n"
+                                     + String.Join("\n", jobs.Select(x => x.Job.Name)),
+          "HeuristicLab Hive Administrator",
+          MessageBoxButtons.YesNo,
+          MessageBoxIcon.Question);
+
+        if (result == DialogResult.Yes) {
+          var task = System.Threading.Tasks.Task.Factory.StartNew(PauseJobsAsync, jobs);
+          progress.Start();
+          SetEnabledStateOfControls();
+
+          task.ContinueWith((t) => {
+            matrixView.DataGridView.ClearSelection();
+            RefreshJobs();
+            progress.Finish();
+          });
+
+          task.ContinueWith((t) => {
+            matrixView.DataGridView.ClearSelection();
+            RefreshJobs();
+            progress.Finish();
+            MessageBox.Show("An error occured pausing the job(s).", "HeuristicLab Hive Administrator", MessageBoxButtons.OK, MessageBoxIcon.Error);
+          }, TaskContinuationOptions.OnlyOnFaulted);
+        }
+      }
+    }
+
+    private void stopButton_Click(object sender, EventArgs e) {
+      var jobs = GetSelectedJobs();
+
+      if (jobs.Any()) {
+        var result = MessageBox.Show("Do you really want to stop following job(s):\n\n"
+                                     + String.Join("\n", jobs.Select(x => x.Job.Name)),
+          "HeuristicLab Hive Administrator",
+          MessageBoxButtons.YesNo,
+          MessageBoxIcon.Question);
+
+        if (result == DialogResult.Yes) {
+          var task = System.Threading.Tasks.Task.Factory.StartNew(StopJobsAsync, jobs);
+          progress.Start();
+          SetEnabledStateOfControls();
+
+          task.ContinueWith((t) => {
+            matrixView.DataGridView.ClearSelection();
+            RefreshJobs();
+            progress.Finish();
+          });
+
+          task.ContinueWith((t) => {
+            matrixView.DataGridView.ClearSelection();
+            RefreshJobs();
+            progress.Finish();
+            MessageBox.Show("An error occured stopping the job(s).", "HeuristicLab Hive Administrator", MessageBoxButtons.OK, MessageBoxIcon.Error);            
+          }, TaskContinuationOptions.OnlyOnFaulted);
+        }
+      }
+    }
+
+    public event EventHandler IsProgressingChanged;
+    private void OnIsProgressingChanged() {
+      var handler = IsProgressingChanged;
+      if (handler != null) handler(this, EventArgs.Empty);
+    }
     #endregion Event Handlers
 
     #region Helpers
+
+    private IEnumerable<RefreshableJob> GetSelectedJobs() {
+      if (Content == null || matrixView.DataGridView.SelectedRows == null || matrixView.DataGridView.SelectedRows.Count == 0)
+        return Enumerable.Empty<RefreshableJob>() ;
+
+      var jobs = new List<RefreshableJob>();
+      foreach (DataGridViewRow r in matrixView.DataGridView.SelectedRows) {
+        if (((string)r.Cells[0].Value) == JobState.Online.ToString()) {
+          jobs.Add(HiveAdminClient.Instance.Jobs[Content.Id].FirstOrDefault(x => x.Id == Guid.Parse((string) r.Cells[9].Value)));
+        }
+      }
+
+      return jobs;
+    }
+
     private void RefreshJobs() {
       HiveAdminClient.Instance.RefreshJobs();
       UpdateJobs();
+      SetEnabledStateOfControls();
     }
 
@@ -160,23 +306,23 @@
       var jobs = HiveAdminClient.Instance.Jobs[Content.Id];
       var resources = HiveAdminClient.Instance.Resources;
-      string[,] values = new string[jobs.Count, 10];
+      string[,] values = new string[jobs.Count, 11];
 
       for(int i = 0; i < jobs.Count; i++) {
-        var job = jobs.ElementAt(i);
-        
-        values[i, 0] = job.State.ToString();
-        values[i, 1] = job.DateCreated.ToString();
-        values[i, 2] = job.OwnerUsername;
-        values[i, 3] = job.Name;
-        values[i, 4] = job.JobCount.ToString();
-        values[i, 5] = job.CalculatingCount.ToString();
-        values[i, 6] = job.FinishedCount.ToString();
-        values[i, 7] = job.Description;        
-        values[i, 8] = job.Id.ToString();
-        values[i, 9] = job.OwnerUserId.ToString();
+        var job = jobs.ElementAt(i);        
+        values[i, 0] = job.Job.State.ToString();
+        values[i, 1] = job.ExecutionState.ToString();
+        values[i, 2] = job.Job.DateCreated.ToString();
+        values[i, 3] = job.Job.OwnerUsername;
+        values[i, 4] = job.Job.Name;
+        values[i, 5] = job.Job.JobCount.ToString();
+        values[i, 6] = job.Job.CalculatingCount.ToString();
+        values[i, 7] = job.Job.FinishedCount.ToString();
+        values[i, 8] = job.Job.Description;        
+        values[i, 9] = job.Job.Id.ToString();
+        values[i, 10] = job.Job.OwnerUserId.ToString();
       }
       
       var matrix = new StringMatrix(values);
-      matrix.ColumnNames = new string[] { JOB_STATE, JOB_DATECREATED, JOB_OWNER, JOB_NAME, JOB_TASKCOUNT, JOB_CALCULATINGTASKCOUNT, JOB_FINISHEDTASKCOUNT, JOB_DESCRIPTION, JOB_ID, JOB_OWNERID };
+      matrix.ColumnNames = new string[] { JOB_STATE, JOB_EXECUTIONSTATE, JOB_DATECREATED, JOB_OWNER, JOB_NAME, JOB_TASKCOUNT, JOB_CALCULATINGTASKCOUNT, JOB_FINISHEDTASKCOUNT, JOB_DESCRIPTION, JOB_ID, JOB_OWNERID };
       matrix.SortableView = true;
       return matrix;
@@ -205,34 +351,44 @@
             matrixView.DataGridView.Columns[1].MinimumWidth = 108;
           }
-        } else {
-          refreshButton.Enabled = false;
-          removeButton.Enabled = false;
-          matrixView.Content = null;
-        }
-      }
-    }
-
-    private void PauseJobs(List<Guid> jobIds) {
-      try {
-        // TODO
-      } catch (AnonymousUserException) {
-        ShowHiveInformationDialog();
-      }
-    }
-
-    private void StopJobs(List<Guid> jobIds) {
-      try {
-        // TODO
-      } catch (AnonymousUserException) {
-        ShowHiveInformationDialog();
-      }
-    }
-
-    private void DeleteJobs(List<Guid> jobIds) {
-      try {
-        HiveAdminClient.DeleteJobs(jobIds);
-      } catch (AnonymousUserException) {
-        ShowHiveInformationDialog();
-      }
+        } 
+      }
+    }
+
+    private void RefreshJobsAsync() {
+      RefreshJobs();
+    }
+
+    private void ResumeJobsAsync(object jobs) {
+      var jobList = (IEnumerable<RefreshableJob>)jobs;
+      foreach (var job in jobList) {
+        progress.Status = "Resuming job \"" + job.Job.Name + "\"...";
+        HiveAdminClient.ResumeJob(job);
+      }
+    }
+
+    private void PauseJobsAsync(object jobs) {
+      var jobList = (IEnumerable<RefreshableJob>)jobs;
+      foreach (var job in jobList) {
+        progress.Status = "Pausing job \"" + job.Job.Name + "\"...";
+        HiveAdminClient.PauseJob(job);
+      }
+    }
+
+    private void StopJobsAsync(object jobs) {
+      var jobList = (IEnumerable<RefreshableJob>) jobs;
+      foreach (var job in jobList) {        
+        progress.Status = "Stopping job \"" + job.Job.Name + "\"...";
+        HiveAdminClient.StopJob(job);
+      }
+    }
+
+    private void RemoveJobsAsync(object jobs) {
+      var jobList = (IEnumerable<RefreshableJob>)jobs;
+      progress.Start();
+      foreach (var job in jobList) {
+        progress.Status = "Deleting job \"" + job.Job.Name + "\"...";
+        HiveAdminClient.RemoveJob(job);
+      }
+      progress.Finish();
     }
 
Index: /trunk/HeuristicLab.Clients.Hive/3.3/HiveAdminClient.cs
===================================================================
--- /trunk/HeuristicLab.Clients.Hive/3.3/HiveAdminClient.cs	(revision 16207)
+++ /trunk/HeuristicLab.Clients.Hive/3.3/HiveAdminClient.cs	(revision 16208)
@@ -71,6 +71,6 @@
     }
 
-    private Dictionary<Guid, HiveItemCollection<Job>> jobs;
-    public Dictionary<Guid, HiveItemCollection<Job>> Jobs {
+    private Dictionary<Guid, HiveItemCollection<RefreshableJob>> jobs;
+    public Dictionary<Guid, HiveItemCollection<RefreshableJob>> Jobs {
       get { return jobs; }
       set {
@@ -144,5 +144,5 @@
         projects = new ItemList<Project>();
         projectResourceAssignments = new ItemList<AssignedProjectResource>();
-        jobs = new Dictionary<Guid, HiveItemCollection<Job>>();
+        jobs = new Dictionary<Guid, HiveItemCollection<RefreshableJob>>();
         projectNames = new Dictionary<Guid, string>();
         resourceNames = new Dictionary<Guid, string>();
@@ -161,11 +161,14 @@
             service.GetAssignedResourcesForProjectsAdministration(projectIds)
               .ForEach(a => projectResourceAssignments.Add(a));
-            projectIds.ForEach(p => jobs.Add(p, new HiveItemCollection<Job>()));
+            projectIds.ForEach(p => jobs.Add(p, new HiveItemCollection<RefreshableJob>()));
             var unsortedJobs = service.GetJobsByProjectIds(projectIds)
               .OrderBy(x => x.DateCreated).ToList();
 
-            unsortedJobs.Where(j => j.State == JobState.DeletionPending).ToList().ForEach(j => jobs[j.ProjectId].Add(j));
-            unsortedJobs.Where(j => j.State == JobState.StatisticsPending).ToList().ForEach(j => jobs[j.ProjectId].Add(j));
-            unsortedJobs.Where(j => j.State == JobState.Online).ToList().ForEach(j => jobs[j.ProjectId].Add(j));
+            unsortedJobs.Where(j => j.State == JobState.DeletionPending).ToList().ForEach(j => jobs[j.ProjectId].Add(new RefreshableJob(j)));
+            unsortedJobs.Where(j => j.State == JobState.StatisticsPending).ToList().ForEach(j => jobs[j.ProjectId].Add(new RefreshableJob(j)));
+            unsortedJobs.Where(j => j.State == JobState.Online).ToList().ForEach(j => jobs[j.ProjectId].Add(new RefreshableJob(j)));
+
+            foreach (var job in jobs.SelectMany(x => x.Value))
+              LoadLightweightJob(job);
 
             projectNames = service.GetProjectNames();
@@ -307,17 +310,51 @@
     public void RefreshJobs() {
       var projectIds = new List<Guid>();
-      jobs = new Dictionary<Guid, HiveItemCollection<Job>>();
+      jobs = new Dictionary<Guid, HiveItemCollection<RefreshableJob>>();
 
       HiveServiceLocator.Instance.CallHiveService(service => {
         service.GetProjectsForAdministration().ForEach(p => projectIds.Add(p.Id));
         if(projectIds.Any()) {
-          projectIds.ForEach(p => jobs.Add(p, new HiveItemCollection<Job>()));
+          projectIds.ForEach(p => jobs.Add(p, new HiveItemCollection<RefreshableJob>()));
           var unsortedJobs = service.GetJobsByProjectIds(projectIds)
             .OrderBy(x => x.DateCreated).ToList();
-          unsortedJobs.Where(j => j.State == JobState.DeletionPending).ToList().ForEach(j => jobs[j.ProjectId].Add(j));
-          unsortedJobs.Where(j => j.State == JobState.StatisticsPending).ToList().ForEach(j => jobs[j.ProjectId].Add(j));
-          unsortedJobs.Where(j => j.State == JobState.Online).ToList().ForEach(j => jobs[j.ProjectId].Add(j));
+          
+          unsortedJobs.Where(j => j.State == JobState.DeletionPending).ToList().ForEach(j => jobs[j.ProjectId].Add(new RefreshableJob(j)));
+          unsortedJobs.Where(j => j.State == JobState.StatisticsPending).ToList().ForEach(j => jobs[j.ProjectId].Add(new RefreshableJob(j)));
+          unsortedJobs.Where(j => j.State == JobState.Online).ToList().ForEach(j => jobs[j.ProjectId].Add(new RefreshableJob(j)));
+
+          foreach(var job in jobs.SelectMany(x => x.Value))
+            LoadLightweightJob(job);
         }
       });
+    }
+
+    public static void LoadLightweightJob(RefreshableJob refreshableJob) {
+      var job = refreshableJob.Job;
+      var tasks = HiveServiceLocator.Instance.CallHiveService(s => s.GetLightweightJobTasksWithoutStateLog(job.Id));
+      if (tasks != null && tasks.Count > 0 && tasks.All(x => x.Id != Guid.Empty)) {
+        if (tasks.All(x =>
+          x.State == TaskState.Finished 
+          || x.State == TaskState.Aborted 
+          || x.State == TaskState.Failed)) {
+          refreshableJob.ExecutionState = ExecutionState.Stopped;
+          refreshableJob.RefreshAutomatically = false;
+        } else if (
+          tasks
+            .Where(x => x.ParentTaskId != null)
+            .All(x =>
+              x.State != TaskState.Waiting
+              || x.State != TaskState.Transferring
+              || x.State != TaskState.Calculating)
+          && tasks
+             .Where(x => x.ParentTaskId != null)
+             .Any(x => x.State == TaskState.Paused)) {
+          refreshableJob.ExecutionState = ExecutionState.Paused;
+          refreshableJob.RefreshAutomatically = false;
+        } else if (tasks.Any(x => x.State == TaskState.Calculating 
+                                  || x.State == TaskState.Transferring 
+                                  || x.State == TaskState.Waiting)) {
+          refreshableJob.ExecutionState = ExecutionState.Started;
+        }
+      }
     }
 
@@ -327,8 +364,8 @@
         var unsortedJobs = jobs.Values.ElementAt(i);
 
-        var sortedJobs = new HiveItemCollection<Job>();
-        sortedJobs.AddRange(unsortedJobs.Where(j => j.State == JobState.DeletionPending));
-        sortedJobs.AddRange(unsortedJobs.Where(j => j.State == JobState.StatisticsPending));
-        sortedJobs.AddRange(unsortedJobs.Where(j => j.State == JobState.Online));
+        var sortedJobs = new HiveItemCollection<RefreshableJob>();
+        sortedJobs.AddRange(unsortedJobs.Where(j => j.Job.State == JobState.DeletionPending));
+        sortedJobs.AddRange(unsortedJobs.Where(j => j.Job.State == JobState.StatisticsPending));
+        sortedJobs.AddRange(unsortedJobs.Where(j => j.Job.State == JobState.Online));
 
         jobs[projectId] = sortedJobs;
@@ -405,7 +442,46 @@
     }
 
-    public static void DeleteJobs(List<Guid> jobIds) {
-
+    public static void RemoveJobs(List<Guid> jobIds) {
       HiveServiceLocator.Instance.CallHiveService((s) => s.UpdateJobStates(jobIds, JobState.StatisticsPending));
+    }
+    #endregion
+
+    #region Job Handling
+
+    public static void ResumeJob(RefreshableJob refreshableJob) {
+      HiveServiceLocator.Instance.CallHiveService(service => {
+        foreach (HiveTask task in refreshableJob.GetAllHiveTasks()) {
+          if (task.Task.State == TaskState.Paused) {
+            service.RestartTask(task.Task.Id);
+          }
+        }
+      });
+      refreshableJob.ExecutionState = ExecutionState.Started;
+    }
+
+    public static void PauseJob(RefreshableJob refreshableJob) {
+      HiveServiceLocator.Instance.CallHiveService(service => {
+        foreach (HiveTask task in refreshableJob.GetAllHiveTasks()) {
+          if (task.Task.State != TaskState.Finished && task.Task.State != TaskState.Aborted && task.Task.State != TaskState.Failed)
+            service.PauseTask(task.Task.Id);
+        }
+      });
+      refreshableJob.ExecutionState = ExecutionState.Paused;
+    }
+
+    public static void StopJob(RefreshableJob refreshableJob) {
+      HiveServiceLocator.Instance.CallHiveService(service => {
+        foreach (HiveTask task in refreshableJob.GetAllHiveTasks()) {
+          if (task.Task.State != TaskState.Finished && task.Task.State != TaskState.Aborted && task.Task.State != TaskState.Failed)
+            service.StopTask(task.Task.Id);
+        }
+      });
+      refreshableJob.ExecutionState = ExecutionState.Stopped;
+    }
+
+    public static void RemoveJob(RefreshableJob refreshableJob) {
+      HiveServiceLocator.Instance.CallHiveService((s) => {
+        s.UpdateJobState(refreshableJob.Id, JobState.StatisticsPending);
+      });
     }
     #endregion
Index: /trunk/HeuristicLab.Services.Hive/3.3/HiveService.cs
===================================================================
--- /trunk/HeuristicLab.Services.Hive/3.3/HiveService.cs	(revision 16207)
+++ /trunk/HeuristicLab.Services.Hive/3.3/HiveService.cs	(revision 16208)
@@ -520,15 +520,28 @@
 
     public void UpdateJobState(Guid jobId, DT.JobState jobState) {
-      RoleVerifier.AuthenticateForAnyRole(HiveRoles.Administrator, HiveRoles.Client);
-      AuthorizationManager.AuthorizeForJob(jobId, DT.Permission.Full);
+      if (jobState != JobState.StatisticsPending) return; // only process requests for "StatisticsPending"
+
+      RoleVerifier.AuthenticateForAnyRole(HiveRoles.Administrator, HiveRoles.Client);
+      bool isAdministrator = RoleVerifier.IsInRole(HiveRoles.Administrator);
+      var currentUserId = UserManager.CurrentUserId;
+
       var pm = PersistenceManager;
       using (new PerformanceLogger("UpdateJobState")) {
         var jobDao = pm.JobDao;
+        var projectDao = pm.ProjectDao;
         pm.UseTransaction(() => {
           var job = jobDao.GetById(jobId);
           if (job != null) {
+
+            var administrationGrantedProjects = projectDao
+              .GetAdministrationGrantedProjectsForUser(currentUserId)
+              .ToList();
+
+            // check if user is an admin, or granted to administer a job-parenting project,...
+            if (!isAdministrator && !administrationGrantedProjects.Contains(job.Project))
+              AuthorizationManager.AuthorizeForJob(jobId, DT.Permission.Full); // ... or job owner
+
+            // note: allow solely state changes from "Online" to "StatisticsPending" = deletion request by user for HiveStatisticGenerator            
             var jobStateEntity = jobState.ToEntity();
-            // note: allow solely state changes from "Online" to "StatisticsPending" = deletion request by user for HiveStatisticGenerator
-            // and from "StatisticsPending" to "DeletionPending" = deletion request by HiveStatisticGenerator for EventManager
             if (job.State == DA.JobState.Online && jobStateEntity == DA.JobState.StatisticsPending) {
               job.State = jobStateEntity;
@@ -540,7 +553,4 @@
               }
               pm.SubmitChanges();
-            } else if (job.State == DA.JobState.StatisticsPending && jobStateEntity == DA.JobState.DeletionPending) {
-              job.State = jobStateEntity;
-              pm.SubmitChanges();
             }
           }
@@ -561,26 +571,28 @@
         var projectDao = pm.ProjectDao;
         pm.UseTransaction(() => {
+          var administrationGrantedProjects = projectDao
+            .GetAdministrationGrantedProjectsForUser(currentUserId)
+            .ToList();
+
           foreach (var jobId in jobIds) {
             var job = jobDao.GetById(jobId);
             if (job != null) {
 
-              var administrationGrantedProjects = projectDao
-                .GetAdministrationGrantedProjectsForUser(currentUserId)
-                .ToList();
-
-              // check if user is granted to administer the job-parenting project
-              if (isAdministrator || administrationGrantedProjects.Contains(job.Project)) {
-                // note: allow solely state changes from "Online" to "StatisticsPending" = deletion request by user for HiveStatisticGenerator
-                if (job.State == DA.JobState.Online) {
-                  job.State = DA.JobState.StatisticsPending;
-                  foreach (var task in job.Tasks
-                  .Where(x => x.State == DA.TaskState.Waiting
-                    || x.State == DA.TaskState.Paused
-                    || x.State == DA.TaskState.Offline)) {
-                    task.State = DA.TaskState.Aborted;
-                  }
-                  pm.SubmitChanges();
+              // check if user is an admin, or granted to administer a job-parenting project,...
+              if (!isAdministrator && !administrationGrantedProjects.Contains(job.Project))
+                AuthorizationManager.AuthorizeForJob(jobId, DT.Permission.Full); // ... or job owner
+
+              // note: allow solely state changes from "Online" to "StatisticsPending" = deletion request by user for HiveStatisticGenerator
+              var jobStateEntity = jobState.ToEntity();
+              if (job.State == DA.JobState.Online && jobStateEntity == DA.JobState.StatisticsPending) {
+                job.State = jobStateEntity;
+                foreach (var task in job.Tasks
+                .Where(x => x.State == DA.TaskState.Waiting
+                  || x.State == DA.TaskState.Paused
+                  || x.State == DA.TaskState.Offline)) {
+                  task.State = DA.TaskState.Aborted;
                 }
-              }
+                pm.SubmitChanges();
+              }              
             }
           }
