Index: /trunk/sources/HeuristicLab.Clients.Access.Views/3.3/ClientViews/ClientView.cs
===================================================================
--- /trunk/sources/HeuristicLab.Clients.Access.Views/3.3/ClientViews/ClientView.cs	(revision 8164)
+++ /trunk/sources/HeuristicLab.Clients.Access.Views/3.3/ClientViews/ClientView.cs	(revision 8165)
@@ -35,9 +35,26 @@
 
     private ProgressView progressView;
-    IProgress progress;
+    private Progress progress;
 
     public ClientView() {
       InitializeComponent();
-      progressView = new ProgressView(this);
+      progress = new Progress() {
+        CanBeCanceled = false,
+        ProgressState = ProgressState.Finished
+      };
+    }
+
+    protected override void DeregisterContentEvents() {
+      if (progressView != null) {
+        progressView.Content = null;
+        progressView.Dispose();
+        progressView = null;
+      }
+      base.DeregisterContentEvents();
+    }
+
+    protected override void RegisterContentEvents() {
+      base.RegisterContentEvents();
+      progressView = new ProgressView(this, progress);
     }
 
@@ -84,7 +101,6 @@
         Invoke(new Action(StartProgressView));
       } else {
-        progress = new Progress();
         progress.Status = "Downloading client information. Please be patient.";
-        progressView.Progress = progress;
+        progress.ProgressState = ProgressState.Started;
       }
     }
Index: /trunk/sources/HeuristicLab.Clients.Hive.JobManager/3.3/Views/HiveResourceSelector.cs
===================================================================
--- /trunk/sources/HeuristicLab.Clients.Hive.JobManager/3.3/Views/HiveResourceSelector.cs	(revision 8164)
+++ /trunk/sources/HeuristicLab.Clients.Hive.JobManager/3.3/Views/HiveResourceSelector.cs	(revision 8165)
@@ -42,5 +42,6 @@
     private ISet<TreeNode> filteredTreeNodes;
     private ISet<TreeNode> nodeStore;
-    private IProgress currentProgress;
+    private Progress progress;
+    private ProgressView progressView;
 
     private ISet<Resource> selectedResources;
@@ -48,10 +49,4 @@
       get { return selectedResources; }
       set { selectedResources = value; }
-    }
-
-    private ProgressView progressView;
-    public ProgressView ProgressView {
-      get { return progressView; }
-      set { progressView = value; }
     }
 
@@ -69,4 +64,22 @@
       imageList.Images.Add(HeuristicLab.Common.Resources.VSImageLibrary.MonitorLarge);
       imageList.Images.Add(HeuristicLab.Common.Resources.VSImageLibrary.NetworkCenterLarge);
+      progress = new Progress() {
+        CanBeCanceled = false,
+        ProgressState = ProgressState.Finished
+      };
+    }
+
+    protected override void DeregisterContentEvents() {
+      if (progressView != null) {
+        progressView.Content = null;
+        progressView.Dispose();
+        progressView = null;
+      }
+      base.DeregisterContentEvents();
+    }
+
+    protected override void RegisterContentEvents() {
+      base.RegisterContentEvents();
+      progressView = new ProgressView(this, progress);
     }
 
@@ -75,10 +88,6 @@
         Invoke(new Action(StartProgressView));
       } else {
-        currentProgress = new Progress();
-        currentProgress.Status = "Downloading resources. Please be patient.";
-        if (progressView == null) {
-          progressView = new ProgressView(this);
-        }
-        progressView.Progress = currentProgress;
+        progress.Status = "Downloading resources. Please be patient.";
+        progress.ProgressState = ProgressState.Started;
       }
     }
@@ -88,5 +97,5 @@
         Invoke(new Action(FinishProgressView));
       } else {
-        currentProgress.Finish();
+        progress.Finish();
       }
     }
Index: /trunk/sources/HeuristicLab.Clients.Hive.JobManager/3.3/Views/HiveResourceSelectorDialog.Designer.cs
===================================================================
--- /trunk/sources/HeuristicLab.Clients.Hive.JobManager/3.3/Views/HiveResourceSelectorDialog.Designer.cs	(revision 8164)
+++ /trunk/sources/HeuristicLab.Clients.Hive.JobManager/3.3/Views/HiveResourceSelectorDialog.Designer.cs	(revision 8165)
@@ -73,5 +73,4 @@
       this.hiveResourceSelector.Location = new System.Drawing.Point(12, 12);
       this.hiveResourceSelector.Name = "hiveResourceSelector";
-      this.hiveResourceSelector.ProgressView = null;
       this.hiveResourceSelector.ReadOnly = false;
       this.hiveResourceSelector.Size = new System.Drawing.Size(549, 591);
Index: /trunk/sources/HeuristicLab.Clients.Hive.JobManager/3.3/Views/RefreshableHiveJobView.cs
===================================================================
--- /trunk/sources/HeuristicLab.Clients.Hive.JobManager/3.3/Views/RefreshableHiveJobView.cs	(revision 8164)
+++ /trunk/sources/HeuristicLab.Clients.Hive.JobManager/3.3/Views/RefreshableHiveJobView.cs	(revision 8165)
@@ -42,4 +42,5 @@
   [Content(typeof(RefreshableJob), true)]
   public partial class RefreshableHiveJobView : HeuristicLab.Core.Views.ItemView {
+    private Progress progress;
     private ProgressView progressView;
     private HiveResourceSelectorDialog hiveResourceSelectorDialog;
@@ -55,5 +56,8 @@
     public RefreshableHiveJobView() {
       InitializeComponent();
-      progressView = new ProgressView(this);
+      progress = new Progress() {
+        CanBeCanceled = true,
+        ProgressState = ProgressState.Finished
+      };
     }
 
@@ -73,4 +77,5 @@
       Content.Loaded += new EventHandler(Content_Loaded);
       Content.TaskReceived += new EventHandler(Content_TaskReceived);
+      progressView = new ProgressView(this, progress);
     }
 
@@ -88,4 +93,9 @@
       Content.Loaded -= new EventHandler(Content_Loaded);
       Content.TaskReceived -= new EventHandler(Content_TaskReceived);
+      if (progressView != null) {
+        progressView.Content = null;
+        progressView.Dispose();
+        progressView = null;
+      }
       base.DeregisterContentEvents();
     }
@@ -356,5 +366,5 @@
         var task = System.Threading.Tasks.Task.Factory.StartNew(ResumeJobAsync, Content);
         task.ContinueWith((t) => {
-          FinishProgressView();
+          progress.Finish();
           MessageBox.Show("An error occured resuming the job. See the log for more information.", "HeuristicLab Hive Job Manager", MessageBoxButtons.OK, MessageBoxIcon.Error);
           Content.Log.LogException(t.Exception);
@@ -368,5 +378,5 @@
       var task = System.Threading.Tasks.Task.Factory.StartNew(PauseJobAsync, Content);
       task.ContinueWith((t) => {
-        FinishProgressView();
+        progress.Finish();
         MessageBox.Show("An error occured pausing the job. See the log for more information.", "HeuristicLab Hive Job Manager", MessageBoxButtons.OK, MessageBoxIcon.Error);
         Content.Log.LogException(t.Exception);
@@ -377,5 +387,5 @@
       var task = System.Threading.Tasks.Task.Factory.StartNew(StopJobAsync, Content);
       task.ContinueWith((t) => {
-        FinishProgressView();
+        progress.Finish();
         MessageBox.Show("An error occured stopping the job. See the log for more information.", "HeuristicLab Hive Job Manager", MessageBoxButtons.OK, MessageBoxIcon.Error);
         Content.Log.LogException(t.Exception);
@@ -385,25 +395,19 @@
 
     private void PauseJobAsync(object job) {
-      IProgress prog = new Progress();
-      prog.Status = "Pausing job...";
-      SetProgressView(prog);
+      progress.Status = "Pausing job...";
+      progress.ProgressState = ProgressState.Started;
       HiveClient.PauseJob((RefreshableJob)job);
-      FinishProgressView();
     }
 
     private void StopJobAsync(object job) {
-      IProgress prog = new Progress();
-      prog.Status = "Stopping job...";
-      SetProgressView(prog);
+      progress.Status = "Stopping job...";
+      progress.ProgressState = ProgressState.Started;
       HiveClient.StopJob((RefreshableJob)job);
-      FinishProgressView();
     }
 
     private void ResumeJobAsync(object job) {
-      IProgress prog = new Progress();
-      prog.Status = "Resuming job...";
-      SetProgressView(prog);
+      progress.Status = "Resuming job...";
+      progress.ProgressState = ProgressState.Started;
       HiveClient.ResumeJob((RefreshableJob)job);
-      FinishProgressView();
     }
 
@@ -466,33 +470,8 @@
       } else {
         if (Content != null && Content.Progress != null && Content.IsProgressing) {
-          SetProgressView();
+          progressView.Content = Content.Progress;
         } else {
-          progressView.Progress = null;
-        }
-      }
-    }
-
-    private void SetProgressView() {
-      if (InvokeRequired) {
-        Invoke(new Action(SetProgressView));
-      } else {
-        progressView.Progress = Content.Progress;
-      }
-    }
-
-    private void SetProgressView(IProgress progress) {
-      if (InvokeRequired) {
-        Invoke(new Action<IProgress>(SetProgressView), progress);
-      } else {
-        progressView.Progress = progress;
-      }
-    }
-
-    private void FinishProgressView() {
-      if (InvokeRequired) {
-        Invoke(new Action(FinishProgressView));
-      } else {
-        if (Content != null && Content.Progress != null)
-          Content.Progress.Finish();
+          progressView.Content = progress;
+        }
       }
     }
Index: /trunk/sources/HeuristicLab.Clients.Hive.Views/3.3/HiveTasks/OptimizerHiveTaskView.cs
===================================================================
--- /trunk/sources/HeuristicLab.Clients.Hive.Views/3.3/HiveTasks/OptimizerHiveTaskView.cs	(revision 8164)
+++ /trunk/sources/HeuristicLab.Clients.Hive.Views/3.3/HiveTasks/OptimizerHiveTaskView.cs	(revision 8165)
@@ -31,6 +31,5 @@
   [Content(typeof(OptimizerHiveTask), true)]
   public partial class OptimizerHiveTaskView : HiveTaskView {
-    private ProgressView progressView;
-    private IProgress progress;
+    private Progress progress;
 
     public new OptimizerHiveTask Content {
@@ -45,5 +44,7 @@
     public OptimizerHiveTaskView() {
       InitializeComponent();
-      progressView = new ProgressView(this);
+      progress = new Progress() {
+        CanBeCanceled = false
+      };
     }
 
@@ -76,5 +77,5 @@
       var task = System.Threading.Tasks.Task.Factory.StartNew(ResumeTaskAsync);
       task.ContinueWith((t) => {
-        FinishProgressView();
+        progress.Finish();
         ErrorHandling.ShowErrorDialog(this, "An error occured while resuming the task.", t.Exception);
       }, TaskContinuationOptions.OnlyOnFaulted);
@@ -84,5 +85,5 @@
       var task = System.Threading.Tasks.Task.Factory.StartNew(PauseTaskAsync);
       task.ContinueWith((t) => {
-        FinishProgressView();
+        progress.Finish();
         ErrorHandling.ShowErrorDialog(this, "An error occured while pausing the task.", t.Exception);
       }, TaskContinuationOptions.OnlyOnFaulted);
@@ -92,5 +93,5 @@
       var task = System.Threading.Tasks.Task.Factory.StartNew(StopTaskAsync);
       task.ContinueWith((t) => {
-        FinishProgressView();
+        progress.Finish();
         ErrorHandling.ShowErrorDialog(this, "An error occured while stopping the task.", t.Exception);
       }, TaskContinuationOptions.OnlyOnFaulted);
@@ -99,40 +100,24 @@
 
     private void PauseTaskAsync() {
-      progress = new Progress();
       progress.Status = "Pausing task. Please be patient for the command to take effect.";
-      SetProgressView(progress);
-      Content.Pause();
-      FinishProgressView();
+      progress.ProgressState = ProgressState.Started;
+      using (var view = new ProgressView(this, progress)) {
+        Content.Pause();
+      }
     }
 
     private void StopTaskAsync() {
-      progress = new Progress();
       progress.Status = "Stopping task. Please be patient for the command to take effect.";
-      SetProgressView(progress);
-      Content.Stop();
-      FinishProgressView();
+      progress.ProgressState = ProgressState.Started;
+      using (var view = new ProgressView(this, progress)) {
+        Content.Stop();
+      }
     }
 
     private void ResumeTaskAsync() {
-      progress = new Progress();
       progress.Status = "Resuming task. Please be patient for the command to take effect.";
-      SetProgressView(progress);
-      Content.Restart();
-      FinishProgressView();
-    }
-
-    private void SetProgressView(IProgress progress) {
-      if (InvokeRequired) {
-        Invoke(new Action<IProgress>(SetProgressView), progress);
-      } else {
-        progressView.Progress = progress;
-      }
-    }
-
-    private void FinishProgressView() {
-      if (InvokeRequired) {
-        Invoke(new Action(FinishProgressView));
-      } else {
-        progress.Finish();
+      progress.ProgressState = ProgressState.Started;
+      using (var view = new ProgressView(this, progress)) {
+        Content.Restart();
       }
     }
Index: /trunk/sources/HeuristicLab.Clients.Hive/3.3/HiveClient.cs
===================================================================
--- /trunk/sources/HeuristicLab.Clients.Hive/3.3/HiveClient.cs	(revision 8164)
+++ /trunk/sources/HeuristicLab.Clients.Hive/3.3/HiveClient.cs	(revision 8165)
@@ -351,5 +351,5 @@
     /// </summary>
     /// <param name="parentHiveTask">shall be null if its the root task</param>
-    private void UploadTaskWithChildren(IProgress progress, HiveTask hiveTask, HiveTask parentHiveTask, IEnumerable<Guid> groups, int[] taskCount, int totalJobCount, Guid configPluginId, Guid jobId, ILog log, bool isPrivileged, CancellationToken cancellationToken) {
+    private void UploadTaskWithChildren(Progress progress, HiveTask hiveTask, HiveTask parentHiveTask, IEnumerable<Guid> groups, int[] taskCount, int totalJobCount, Guid configPluginId, Guid jobId, ILog log, bool isPrivileged, CancellationToken cancellationToken) {
       taskUploadSemaphore.WaitOne();
       bool semaphoreReleased = false;
Index: /trunk/sources/HeuristicLab.Clients.Hive/3.3/RefreshableJob.cs
===================================================================
--- /trunk/sources/HeuristicLab.Clients.Hive/3.3/RefreshableJob.cs	(revision 8164)
+++ /trunk/sources/HeuristicLab.Clients.Hive/3.3/RefreshableJob.cs	(revision 8165)
@@ -167,6 +167,6 @@
     }
 
-    private IProgress progress;
-    public IProgress Progress {
+    private Progress progress;
+    public Progress Progress {
       get { return progress; }
       set {
Index: /trunk/sources/HeuristicLab.Clients.OKB.Views/3.3/RunCreation/Views/OKBExperimentUploadView.cs
===================================================================
--- /trunk/sources/HeuristicLab.Clients.OKB.Views/3.3/RunCreation/Views/OKBExperimentUploadView.cs	(revision 8164)
+++ /trunk/sources/HeuristicLab.Clients.OKB.Views/3.3/RunCreation/Views/OKBExperimentUploadView.cs	(revision 8165)
@@ -39,7 +39,5 @@
     public new IOptimizer Content {
       get { return (IOptimizer)base.Content; }
-      set {
-        base.Content = value;
-      }
+      set { base.Content = value; }
     }
 
@@ -56,10 +54,13 @@
     Algorithm selectedAlgorithm = null;
     Problem selectedProblem = null;
-    private ProgressView progressView;
-    private IProgress progress;
+    private ProgressView progressView; // this has to be disposed manually!
+    private Progress progress;
 
     public OKBExperimentUploadView() {
       InitializeComponent();
-      progressView = new ProgressView(this);
+      progress = new Progress() {
+        CanBeCanceled = false,
+        ProgressState = ProgressState.Finished
+      };
     }
 
@@ -95,4 +96,5 @@
       RunCreationClient.Instance.Refreshing += new EventHandler(RunCreationClient_Refreshing);
       RunCreationClient.Instance.Refreshed += new EventHandler(RunCreationClient_Refreshed);
+      progressView = new ProgressView(this, progress);
     }
 
@@ -100,4 +102,9 @@
       RunCreationClient.Instance.Refreshing -= new EventHandler(RunCreationClient_Refreshing);
       RunCreationClient.Instance.Refreshed -= new EventHandler(RunCreationClient_Refreshed);
+      if (progressView != null) {
+        progressView.Content = null;
+        progressView.Dispose();
+        progressView = null;
+      }
       base.DeregisterContentEvents();
     }
@@ -191,7 +198,6 @@
         Invoke(new EventHandler(RunCreationClient_Refreshing), sender, e);
       } else {
-        progress = new Progress();
         progress.Status = "Refreshing algorithms and problems...";
-        SetProgressView(progress);
+        progress.ProgressState = ProgressState.Started;
       }
     }
@@ -201,5 +207,5 @@
         Invoke(new EventHandler(RunCreationClient_Refreshed), sender, e);
       } else {
-        FinishProgressView();
+        progress.Finish();
         SetEnabledStateOfControls();
       }
@@ -209,5 +215,5 @@
       var task = System.Threading.Tasks.Task.Factory.StartNew(UploadAsync);
       task.ContinueWith((t) => {
-        FinishProgressView();
+        progress.Finish();
         PluginInfrastructure.ErrorHandling.ShowErrorDialog("An exception occured while uploading the runs to the OKB.", t.Exception);
       }, TaskContinuationOptions.OnlyOnFaulted);
@@ -215,5 +221,4 @@
 
     private void UploadAsync() {
-      progress = new Progress();
       progress.Status = "Uploading runs to OKB...";
       progress.ProgressValue = 0;
@@ -221,35 +226,19 @@
       int i = 0;
 
-      SetProgressView(progress);
-      foreach (DataGridViewRow row in dataGridView.Rows) {
-        selectedAlgorithm = algorithms.Where(x => x.Name == row.Cells[algorithmColumnIndex].Value.ToString()).FirstOrDefault();
-        selectedProblem = problems.Where(x => x.Name == row.Cells[problemColumnIndex].Value.ToString()).FirstOrDefault();
-        if (selectedAlgorithm == null || selectedProblem == null) {
-          throw new ArgumentException("Can't retrieve the algorithm/problem to upload");
-        }
-
-        OKBRun run = new OKBRun(selectedAlgorithm.Id, selectedProblem.Id, row.Tag as IRun, UserInformation.Instance.User.Id);
-        run.Store();
-        i++;
-        progress.ProgressValue = ((double)i) / count;
-      }
-      FinishProgressView();
+      using (var view = new ProgressView(this, progress)) {
+        foreach (DataGridViewRow row in dataGridView.Rows) {
+          selectedAlgorithm = algorithms.Where(x => x.Name == row.Cells[algorithmColumnIndex].Value.ToString()).FirstOrDefault();
+          selectedProblem = problems.Where(x => x.Name == row.Cells[problemColumnIndex].Value.ToString()).FirstOrDefault();
+          if (selectedAlgorithm == null || selectedProblem == null) {
+            throw new ArgumentException("Can't retrieve the algorithm/problem to upload");
+          }
+
+          OKBRun run = new OKBRun(selectedAlgorithm.Id, selectedProblem.Id, row.Tag as IRun, UserInformation.Instance.User.Id);
+          run.Store();
+          i++;
+          progress.ProgressValue = ((double)i) / count;
+        }
+      }
       ClearRuns();
-    }
-
-    private void SetProgressView(IProgress progress) {
-      if (InvokeRequired) {
-        Invoke(new Action<IProgress>(SetProgressView), progress);
-      } else {
-        progressView.Progress = progress;
-      }
-    }
-
-    private void FinishProgressView() {
-      if (InvokeRequired) {
-        Invoke(new Action(FinishProgressView));
-      } else {
-        progress.Finish();
-      }
     }
 
Index: /trunk/sources/HeuristicLab.MainForm.WindowsForms/3.3/Views/ProgressView.cs
===================================================================
--- /trunk/sources/HeuristicLab.MainForm.WindowsForms/3.3/Views/ProgressView.cs	(revision 8164)
+++ /trunk/sources/HeuristicLab.MainForm.WindowsForms/3.3/Views/ProgressView.cs	(revision 8165)
@@ -21,78 +21,105 @@
 
 using System;
+using System.ComponentModel;
 using System.Windows.Forms;
 
 namespace HeuristicLab.MainForm.WindowsForms {
-  public partial class ProgressView : HeuristicLab.MainForm.WindowsForms.View {
+  [View("ProgressView")]
+  [Content(typeof(IProgress), true)]
+  public partial class ProgressView : AsynchronousContentView {
+    private const int DefaultCancelTimeoutMs = 3000;
     private ContentView parentView;
 
-    private IProgress progress;
-    public IProgress Progress {
-      get { return progress; }
-      set {
-        if (progress == value) return;
-        Finish();
-        progress = value;
-        RegisterProgressEvents();
-        ShowProgress();
-        OnProgressChanged();
-      }
-    }
-
-    private bool cancelEnabled;
-    public bool CancelEnabled {
-      get { return cancelEnabled; }
-      set {
-        cancelEnabled = value;
-        SetCancelButtonVisibility();
-      }
+    [Category("Custom"), Description("The time that the process is allowed to exit.")]
+    [DefaultValue(DefaultCancelTimeoutMs)]
+    public int CancelTimeoutMs { get; set; }
+    private bool ShouldSerializeCancelTimeoutMs() { return CancelTimeoutMs != DefaultCancelTimeoutMs; }
+
+    public new IProgress Content {
+      get { return (IProgress)base.Content; }
+      set { base.Content = value; }
+    }
+
+    public ProgressView() {
+      InitializeComponent();
+    }
+    public ProgressView(IProgress progress)
+      : this() {
+      Content = progress;
+    }
+    public ProgressView(ContentView parentView)
+      : this() {
+      if (parentView == null) throw new ArgumentNullException("parentView", "The parent view is null.");
+      this.parentView = parentView;
+    }
+    public ProgressView(ContentView parentView, IProgress progress)
+      : this(parentView) {
+      Content = progress;
+    }
+
+    protected override void RegisterContentEvents() {
+      Content.StatusChanged += new EventHandler(progress_StatusChanged);
+      Content.ProgressValueChanged += new EventHandler(progress_ProgressValueChanged);
+      Content.ProgressStateChanged += new EventHandler(Content_ProgressStateChanged);
+      Content.CanBeCanceledChanged += new EventHandler(Content_CanBeCanceledChanged);
+      base.RegisterContentEvents();
+    }
+
+    protected override void DeregisterContentEvents() {
+      base.DeregisterContentEvents();
+      Content.StatusChanged -= new EventHandler(progress_StatusChanged);
+      Content.ProgressValueChanged -= new EventHandler(progress_ProgressValueChanged);
+      Content.ProgressStateChanged -= new EventHandler(Content_ProgressStateChanged);
+      Content.CanBeCanceledChanged -= new EventHandler(Content_CanBeCanceledChanged);
+    }
+
+    protected override void OnContentChanged() {
+      base.OnContentChanged();
+      if (Content == null) {
+        HideProgress();
+      } else {
+        if (Content.ProgressState == ProgressState.Started)
+          ShowProgress();
+      }
+    }
+
+    protected override void SetEnabledStateOfControls() {
+      base.SetEnabledStateOfControls();
+      cancelButton.Visible = Content != null && Content.CanBeCanceled;
+      cancelButton.Enabled = Content != null && Content.CanBeCanceled && !ReadOnly;
     }
 
     private void ShowProgress() {
-      if (progress != null) {
-        this.Left = (parentView.ClientRectangle.Width / 2) - (this.Width / 2);
-        this.Top = (parentView.ClientRectangle.Height / 2) - (this.Height / 2);
-        this.Anchor = AnchorStyles.Left | AnchorStyles.Top;
-
-        LockBackground();
-
-        if (!parentView.Controls.Contains(this)) {
-          parentView.Controls.Add(this);
-        }
-
-        BringToFront();
+      if (InvokeRequired) Invoke((Action)ShowProgress);
+      else {
+        if (parentView != null) {
+          this.Left = (parentView.ClientRectangle.Width / 2) - (this.Width / 2);
+          this.Top = (parentView.ClientRectangle.Height / 2) - (this.Height / 2);
+          this.Anchor = AnchorStyles.None;
+
+          LockBackground();
+
+          if (!parentView.Controls.Contains(this))
+            parentView.Controls.Add(this);
+
+          BringToFront();
+        }
+        UpdateProgressValue();
+        UpdateProgressStatus();
         Visible = true;
       }
     }
 
-    public ProgressView(ContentView parentView) {
-      InitializeComponent();
-      CancelEnabled = false;
-
-      if (parentView != null) {
-        this.parentView = parentView;
-      } else {
-        throw new ArgumentNullException("The parent view is null.");
-      }
-    }
-
-    private void RegisterProgressEvents() {
-      if (progress == null) return;
-      progress.Finished += new EventHandler(progress_Finished);
-      progress.StatusChanged += new EventHandler(progress_StatusChanged);
-      progress.ProgressValueChanged += new EventHandler(progress_ProgressValueChanged);
-      progress.Canceled += new EventHandler(progress_Canceled);
-    }
-
-    private void DeregisterProgressEvents() {
-      if (progress == null) return;
-      progress.Finished -= new EventHandler(progress_Finished);
-      progress.StatusChanged -= new EventHandler(progress_StatusChanged);
-      progress.ProgressValueChanged -= new EventHandler(progress_ProgressValueChanged);
-      progress.Canceled -= new EventHandler(progress_Canceled);
-    }
-
-    private void progress_Finished(object sender, EventArgs e) {
-      Finish();
+    private void HideProgress() {
+      if (InvokeRequired) Invoke((Action)HideProgress);
+      else {
+        if (parentView != null) {
+          if (parentView.Controls.Contains(this))
+            parentView.Controls.Remove(this);
+
+          UnlockBackground();
+        }
+        Visible = false;
+      }
     }
 
@@ -105,6 +132,14 @@
     }
 
-    void progress_Canceled(object sender, EventArgs e) {
-      Finish();
+    private void Content_ProgressStateChanged(object sender, EventArgs e) {
+      if (Content.ProgressState == ProgressState.Finished
+        || Content.ProgressState == ProgressState.Canceled)
+        HideProgress();
+      if (Content.ProgressState == ProgressState.Started)
+        ShowProgress();
+    }
+
+    private void Content_CanBeCanceledChanged(object sender, EventArgs e) {
+      SetEnabledStateOfControls();
     }
 
@@ -115,6 +150,16 @@
         parentView.Locked = true;
         parentView.ReadOnly = true;
-        Enabled = true;
+        Locked = false;
         ReadOnly = false;
+      }
+    }
+
+    private void UnlockBackground() {
+      if (InvokeRequired) Invoke((Action)UnlockBackground);
+      else {
+        parentView.Locked = false;
+        parentView.ReadOnly = false;
+        Locked = true;
+        ReadOnly = true;
       }
     }
@@ -123,11 +168,12 @@
       if (InvokeRequired) Invoke((Action)UpdateProgressValue);
       else {
-        if (progress != null) {
-          double progressValue = progress.ProgressValue;
-          if (progressValue < progressBar.Minimum || progressValue > progressBar.Maximum) {
-            progressBar.Style = ProgressBarStyle.Marquee;
-            progressBar.Value = progressBar.Minimum;
+        if (Content != null) {
+          double progressValue = Content.ProgressValue;
+          if (progressValue <= 0.0 || progressValue > 1.0) {
+            if (progressBar.Style != ProgressBarStyle.Marquee)
+              progressBar.Style = ProgressBarStyle.Marquee;
           } else {
-            progressBar.Style = ProgressBarStyle.Blocks;
+            if (progressBar.Style != ProgressBarStyle.Blocks)
+              progressBar.Style = ProgressBarStyle.Blocks;
             progressBar.Value = (int)Math.Round(progressBar.Minimum + progressValue * (progressBar.Maximum - progressBar.Minimum));
           }
@@ -138,44 +184,24 @@
     private void UpdateProgressStatus() {
       if (InvokeRequired) Invoke((Action)UpdateProgressStatus);
-      else {
-        if (progress != null) {
-          string status = progress.Status;
-          statusLabel.Text = progress.Status;
-        }
-      }
-    }
-
-    private void Finish() {
-      if (InvokeRequired) {
-        Invoke(new Action(Finish));
-      } else {
-        progressBar.Value = progressBar.Maximum;
-        parentView.Controls.Remove(this);
-        parentView.Locked = false;
-        parentView.ReadOnly = false;
-        DeregisterProgressEvents();
-        progress = null;
-        Visible = false;
-      }
+      else if (Content != null)
+        statusLabel.Text = Content.Status;
     }
 
     private void cancelButton_Click(object sender, EventArgs e) {
-      if (progress != null) {
-        progress.CancelRequested = true;
-        cancelButton.Enabled = false;
-      }
-    }
-
-    private void SetCancelButtonVisibility() {
-      if (InvokeRequired) {
-        Invoke((Action)SetCancelButtonVisibility);
-      } else {
-        cancelButton.Visible = cancelEnabled;
-      }
-    }
-
-    private void OnProgressChanged() {
-      UpdateProgressStatus();
-      UpdateProgressValue();
+      if (Content != null) {
+        try {
+          Content.Cancel(CancelTimeoutMs);
+          ReadOnly = true;
+          cancelButtonTimer.Interval = CancelTimeoutMs;
+          cancelButtonTimer.Start();
+        } catch (NotSupportedException nse) {
+          PluginInfrastructure.ErrorHandling.ShowErrorDialog(nse);
+        }
+      }
+    }
+
+    private void cancelButtonTimer_Tick(object sender, EventArgs e) {
+      cancelButtonTimer.Stop();
+      if (Visible) ReadOnly = false;
     }
   }
Index: /trunk/sources/HeuristicLab.MainForm.WindowsForms/3.3/Views/ProgressView.designer.cs
===================================================================
--- /trunk/sources/HeuristicLab.MainForm.WindowsForms/3.3/Views/ProgressView.designer.cs	(revision 8164)
+++ /trunk/sources/HeuristicLab.MainForm.WindowsForms/3.3/Views/ProgressView.designer.cs	(revision 8165)
@@ -1,5 +1,5 @@
 ﻿
 namespace HeuristicLab.MainForm.WindowsForms {
-  partial class ProgressView : View {
+  partial class ProgressView {
     /// <summary> 
     /// Required designer variable.
@@ -25,8 +25,10 @@
     /// </summary>
     private void InitializeComponent() {
+      this.components = new System.ComponentModel.Container();
       this.progressBar = new System.Windows.Forms.ProgressBar();
       this.statusLabel = new System.Windows.Forms.Label();
       this.cancelButton = new System.Windows.Forms.Button();
       this.panel = new System.Windows.Forms.Panel();
+      this.cancelButtonTimer = new System.Windows.Forms.Timer(this.components);
       this.panel.SuspendLayout();
       this.SuspendLayout();
@@ -75,7 +77,10 @@
       this.panel.TabIndex = 3;
       // 
+      // cancelButtonTimer
+      // 
+      this.cancelButtonTimer.Tick += new System.EventHandler(this.cancelButtonTimer_Tick);
+      // 
       // ProgressView
       // 
-      this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
       this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Inherit;
       this.Controls.Add(this.panel);
@@ -93,4 +98,5 @@
     private System.Windows.Forms.Button cancelButton;
     private System.Windows.Forms.Panel panel;
+    private System.Windows.Forms.Timer cancelButtonTimer;
   }
 }
Index: /trunk/sources/HeuristicLab.MainForm/3.3/Interfaces/IProgress.cs
===================================================================
--- /trunk/sources/HeuristicLab.MainForm/3.3/Interfaces/IProgress.cs	(revision 8164)
+++ /trunk/sources/HeuristicLab.MainForm/3.3/Interfaces/IProgress.cs	(revision 8165)
@@ -21,19 +21,60 @@
 
 using System;
+using HeuristicLab.Common;
 
 namespace HeuristicLab.MainForm {
-  public interface IProgress {
-    string Status { get; set; }
-    double ProgressValue { get; set; }
+  public enum ProgressState { Started = 1, Canceled = 2, Finished = 3 };
 
-    void Finish();
-    void SignalSuccessfulCancelation();
+  public interface IProgress : IContent {
+    /// <summary>
+    /// Gets the currently associated status text with the progress.
+    /// </summary>
+    string Status { get; }
+    /// <summary>
+    /// Gets the currently associated progress value in the range (0;1].
+    ///  Values outside this range are permitted and need to be handled in some feasible manner.
+    /// </summary>
+    double ProgressValue { get; }
+    /// <summary>
+    /// Gets the current state of the progress. Every progress starts in state
+    /// Started and then becomes either Canceled or Finished.
+    /// If it is reused it may be Started again.
+    /// </summary>
+    ProgressState ProgressState { get; }
+    /// <summary>
+    /// Returns whether the operation can be canceled or not.
+    /// This can change during the course of the progress.
+    /// </summary>
+    bool CanBeCanceled { get; }
 
-    bool CancelRequested { get; set; }
+    /// <summary>
+    /// Requests the operation behind the process to cancel.
+    /// Check the !ProgressState property when the cancellation succeeded.
+    /// The corresponding event will also notify of a success.
+    /// </summary>
+    /// <exception cref="NotSupportedException">Thrown when cancellation is not supported.</exception>
+    /// <param name="timeoutMs">The operation is given a certain timeout to cancel. If the operation doesn't cancel in this time it will be forcibly closed.</param>
+    void Cancel(int timeoutMs);
 
-    event EventHandler Finished;
+    /// <summary>
+    /// The status text changed.
+    /// </summary>
     event EventHandler StatusChanged;
+    /// <summary>
+    /// The value of the progress changed. This is the (0;1] progress value from starting to finish. Values outside this range are permitted and need to be handled in some feasible manner.
+    /// </summary>
     event EventHandler ProgressValueChanged;
-    event EventHandler Canceled;
+    /// <summary>
+    /// The state of the progress changed. The handler is supposed to query the ProgressState property.
+    /// </summary>
+    event EventHandler ProgressStateChanged;
+    /// <summary>
+    /// The progress' ability to cancel changed.
+    /// </summary>
+    event EventHandler CanBeCanceledChanged;
+    /// <summary>
+    /// A cancelation is requested with a certain timeout (in ms) in which it should occur gracefully. If the timeout is surpassed, it should be forcibly canceled.
+    /// </summary>
+    event EventHandler<EventArgs<int>> CancelRequested;
   }
 }
Index: /trunk/sources/HeuristicLab.MainForm/3.3/Progress.cs
===================================================================
--- /trunk/sources/HeuristicLab.MainForm/3.3/Progress.cs	(revision 8164)
+++ /trunk/sources/HeuristicLab.MainForm/3.3/Progress.cs	(revision 8165)
@@ -21,4 +21,5 @@
 
 using System;
+using HeuristicLab.Common;
 
 namespace HeuristicLab.MainForm {
@@ -26,10 +27,8 @@
     private string status;
     public string Status {
-      get {
-        return this.status;
-      }
+      get { return status; }
       set {
-        if (this.status != value) {
-          this.status = value;
+        if (status != value) {
+          status = value;
           OnStatusChanged();
         }
@@ -37,14 +36,10 @@
     }
 
-    public bool CancelRequested { get; set; }
-
     private double progressValue;
     public double ProgressValue {
-      get {
-        return this.progressValue;
-      }
+      get { return progressValue; }
       set {
-        if (this.progressValue != value) {
-          this.progressValue = value;
+        if (progressValue != value) {
+          progressValue = value;
           OnProgressChanged();
         }
@@ -52,37 +47,52 @@
     }
 
-    public Progress() { }
-
-    public Progress(string status) {
-      this.Status = status;
+    private ProgressState progressState;
+    public ProgressState ProgressState {
+      get { return progressState; }
+      set {
+        if (progressState != value) {
+          progressState = value;
+          OnProgressStateChanged();
+        }
+      }
     }
 
-    public void Finish() {
-      OnFinished();
+    private bool canBeCanceled;
+    public bool CanBeCanceled {
+      get { return canBeCanceled; }
+      set {
+        if (canBeCanceled != value) {
+          canBeCanceled = value;
+          OnCanBeCanceledChanged();
+        }
+      }
     }
 
-    public void SignalSuccessfulCancelation() {
-      OnCanceled();
+    public Progress() {
+      progressState = ProgressState.Started;
+    }
+    public Progress(string status)
+      : this() {
+      this.status = status;
+    }
+    public Progress(string status, double progressValue)
+      : this(status) {
+      this.progressValue = progressValue;
+    }
+
+    public void Cancel(int timeoutMs) {
+      if (canBeCanceled)
+        OnCancelRequested(timeoutMs);
+    }
+
+    /// <summary>
+    /// Sets the ProgressValue to 1 and the ProgressState to Finished.
+    /// </summary>
+    public void Finish() {
+      if (ProgressValue != 1.0) ProgressValue = 1.0;
+      ProgressState = ProgressState.Finished;
     }
 
     #region Event Handler
-    public event EventHandler Canceled;
-    private void OnCanceled() {
-      var handler = Canceled;
-      try {
-        if (handler != null) handler(this, EventArgs.Empty);
-      }
-      catch (Exception) { }
-    }
-
-    public event EventHandler Finished;
-    private void OnFinished() {
-      var handler = Finished;
-      try {
-        if (handler != null) handler(this, EventArgs.Empty);
-      }
-      catch (Exception) { }
-    }
-
     public event EventHandler StatusChanged;
     private void OnStatusChanged() {
@@ -90,6 +100,5 @@
       try {
         if (handler != null) handler(this, EventArgs.Empty);
-      }
-      catch (Exception) { }
+      } catch { }
     }
 
@@ -99,6 +108,30 @@
       try {
         if (handler != null) handler(this, EventArgs.Empty);
-      }
-      catch (Exception) { }
+      } catch { }
+    }
+
+    public event EventHandler ProgressStateChanged;
+    private void OnProgressStateChanged() {
+      var handler = ProgressStateChanged;
+      try {
+        if (handler != null) handler(this, EventArgs.Empty);
+      } catch { }
+    }
+
+    public event EventHandler CanBeCanceledChanged;
+    private void OnCanBeCanceledChanged() {
+      var handler = CanBeCanceledChanged;
+      try {
+        if (handler != null) handler(this, EventArgs.Empty);
+      } catch { }
+    }
+
+    public event EventHandler<EventArgs<int>> CancelRequested;
+    private void OnCancelRequested(int timeoutMs) {
+      var handler = CancelRequested;
+      try {
+        if (handler == null) throw new NotSupportedException("Cancel request was ignored.");
+        else handler(this, new EventArgs<int>(timeoutMs));
+      } catch { }
     }
     #endregion
