Index: stable/HeuristicLab.MainForm.WindowsForms/3.3/Controls/ProgressView.cs
===================================================================
--- stable/HeuristicLab.MainForm.WindowsForms/3.3/Controls/ProgressView.cs	(revision 9931)
+++ stable/HeuristicLab.MainForm.WindowsForms/3.3/Controls/ProgressView.cs	(revision 9933)
@@ -21,92 +21,80 @@
 
 using System;
-using System.ComponentModel;
 using System.Windows.Forms;
 
 namespace HeuristicLab.MainForm.WindowsForms {
-  [View("ProgressView")]
-  [Content(typeof(IProgress), true)]
-  public partial class ProgressView : AsynchronousContentView {
-    private const int DefaultCancelTimeoutMs = 3000;
-    private ContentView parentView;
+  internal sealed partial class ProgressView : UserControl {
+    private const int defaultControlHeight = 88;
+    private const int collapsedControlHeight = 55;
 
-    [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; }
+    private readonly Control control;
+    public Control Control {
+      get { return control; }
     }
 
-    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;
+    private readonly IProgress content;
+    public IProgress Content {
+      get { return content; }
     }
 
-    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();
+    public ProgressView(Control control, IProgress content)
+      : base() {
+      if (control == null) throw new ArgumentNullException("control", "The control is null.");
+      if (content == null) throw new ArgumentNullException("content", "The passed progress is null.");
+      InitializeComponent();
+
+      this.control = control;
+      this.content = content;
+      if (content.ProgressState == ProgressState.Started)
+        ShowProgress();
+      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);
+    /// <summary> 
+    /// Clean up any resources being used.
+    /// </summary>
+    /// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
+    protected override void Dispose(bool disposing) {
+      DeregisterContentEvents();
+      HideProgress();
+
+      if (disposing && (components != null)) {
+        components.Dispose();
+      }
+      base.Dispose(disposing);
     }
 
-    protected override void OnContentChanged() {
-      base.OnContentChanged();
-      if (Content == null) {
-        HideProgress();
-      } else {
-        if (Content.ProgressState == ProgressState.Started)
-          ShowProgress();
-      }
+    private 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);
     }
-
-    protected override void SetEnabledStateOfControls() {
-      base.SetEnabledStateOfControls();
-      cancelButton.Visible = Content != null && Content.CanBeCanceled;
-      cancelButton.Enabled = Content != null && Content.CanBeCanceled && !ReadOnly;
+    private void 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);
     }
 
     private void ShowProgress() {
-      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;
+      if (Control.InvokeRequired) {
+        Control.Invoke((Action)ShowProgress);
+        return;
+      }
+      int height = Content.CanBeCanceled ? Height : collapsedControlHeight;
 
-          LockBackground();
+      Left = (Control.ClientRectangle.Width / 2) - (Width / 2);
+      Top = (Control.ClientRectangle.Height / 2) - (height / 2);
+      Anchor = AnchorStyles.None;
 
-          if (!parentView.Controls.Contains(this))
-            parentView.Controls.Add(this);
+      control.Enabled = false;
+      Parent = Control.Parent;
+      BringToFront();
 
-          BringToFront();
-        }
-        UpdateProgressValue();
-        UpdateProgressStatus();
-        Visible = true;
-      }
+      UpdateProgressValue();
+      UpdateProgressStatus();
+      UpdateCancelButton();
+      Visible = true;
     }
 
@@ -114,10 +102,6 @@
       if (InvokeRequired) Invoke((Action)HideProgress);
       else {
-        if (parentView != null) {
-          if (parentView.Controls.Contains(this))
-            parentView.Controls.Remove(this);
-
-          UnlockBackground();
-        }
+        control.Enabled = true;
+        Parent = null;
         Visible = false;
       }
@@ -133,33 +117,24 @@
 
     private void Content_ProgressStateChanged(object sender, EventArgs e) {
-      if (Content.ProgressState == ProgressState.Finished
-        || Content.ProgressState == ProgressState.Canceled)
-        HideProgress();
-      if (Content.ProgressState == ProgressState.Started)
-        ShowProgress();
+      switch (content.ProgressState) {
+        case ProgressState.Finished: HideProgress(); break;
+        case ProgressState.Canceled: HideProgress(); break;
+        case ProgressState.Started: ShowProgress(); break;
+        default: throw new NotSupportedException("The progress state " + content.ProgressState + " is not supported by the ProgressView.");
+      }
     }
 
     private void Content_CanBeCanceledChanged(object sender, EventArgs e) {
-      SetEnabledStateOfControls();
+      UpdateCancelButton();
     }
 
-    private void LockBackground() {
-      if (InvokeRequired) {
-        Invoke((Action)LockBackground);
-      } else {
-        parentView.Locked = true;
-        parentView.ReadOnly = true;
-        Locked = false;
-        ReadOnly = false;
-      }
-    }
+    private void UpdateCancelButton() {
+      cancelButton.Visible = content != null && content.CanBeCanceled;
+      cancelButton.Enabled = content != null && content.CanBeCanceled;
 
-    private void UnlockBackground() {
-      if (InvokeRequired) Invoke((Action)UnlockBackground);
-      else {
-        parentView.Locked = false;
-        parentView.ReadOnly = false;
-        Locked = true;
-        ReadOnly = true;
+      if (content != null && content.CanBeCanceled) {
+        Height = defaultControlHeight;
+      } else if (content != null && !content.CanBeCanceled) {
+        Height = collapsedControlHeight;
       }
     }
@@ -168,12 +143,10 @@
       if (InvokeRequired) Invoke((Action)UpdateProgressValue);
       else {
-        if (Content != null) {
-          double progressValue = Content.ProgressValue;
+        if (content != null) {
+          double progressValue = content.ProgressValue;
           if (progressValue <= 0.0 || progressValue > 1.0) {
-            if (progressBar.Style != ProgressBarStyle.Marquee)
-              progressBar.Style = ProgressBarStyle.Marquee;
+            progressBar.Style = ProgressBarStyle.Marquee;
           } else {
-            if (progressBar.Style != ProgressBarStyle.Blocks)
-              progressBar.Style = ProgressBarStyle.Blocks;
+            progressBar.Style = ProgressBarStyle.Blocks;
             progressBar.Value = (int)Math.Round(progressBar.Minimum + progressValue * (progressBar.Maximum - progressBar.Minimum));
           }
@@ -184,24 +157,10 @@
     private void UpdateProgressStatus() {
       if (InvokeRequired) Invoke((Action)UpdateProgressStatus);
-      else if (Content != null)
-        statusLabel.Text = Content.Status;
+      else if (content != null)
+        statusLabel.Text = content.Status;
     }
 
     private void cancelButton_Click(object sender, EventArgs e) {
-      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;
+      content.Cancel();
     }
   }
Index: stable/HeuristicLab.MainForm.WindowsForms/3.3/Controls/ProgressView.designer.cs
===================================================================
--- stable/HeuristicLab.MainForm.WindowsForms/3.3/Controls/ProgressView.designer.cs	(revision 9931)
+++ stable/HeuristicLab.MainForm.WindowsForms/3.3/Controls/ProgressView.designer.cs	(revision 9933)
@@ -27,15 +27,5 @@
     private System.ComponentModel.IContainer components = null;
 
-    /// <summary> 
-    /// Clean up any resources being used.
-    /// </summary>
-    /// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
-    protected override void Dispose(bool disposing) {
-      if (disposing && (components != null)) {
-        components.Dispose();
-      }
-      base.Dispose(disposing);
-    }
-
+   
     #region Component Designer generated code
 
@@ -45,10 +35,8 @@
     /// </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();
@@ -56,6 +44,6 @@
       // progressBar
       // 
-      this.progressBar.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left)
-                  | System.Windows.Forms.AnchorStyles.Right)));
+      this.progressBar.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left) 
+            | System.Windows.Forms.AnchorStyles.Right)));
       this.progressBar.Location = new System.Drawing.Point(3, 3);
       this.progressBar.Name = "progressBar";
@@ -66,6 +54,6 @@
       // statusLabel
       // 
-      this.statusLabel.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left)
-                  | System.Windows.Forms.AnchorStyles.Right)));
+      this.statusLabel.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left) 
+            | System.Windows.Forms.AnchorStyles.Right)));
       this.statusLabel.Location = new System.Drawing.Point(3, 33);
       this.statusLabel.Name = "statusLabel";
@@ -86,6 +74,7 @@
       // panel
       // 
-      this.panel.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left)
-                  | System.Windows.Forms.AnchorStyles.Right)));
+      this.panel.Anchor = ((System.Windows.Forms.AnchorStyles)((((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom) 
+            | System.Windows.Forms.AnchorStyles.Left) 
+            | System.Windows.Forms.AnchorStyles.Right)));
       this.panel.BorderStyle = System.Windows.Forms.BorderStyle.FixedSingle;
       this.panel.Controls.Add(this.progressBar);
@@ -96,8 +85,4 @@
       this.panel.Size = new System.Drawing.Size(360, 88);
       this.panel.TabIndex = 3;
-      // 
-      // cancelButtonTimer
-      // 
-      this.cancelButtonTimer.Tick += new System.EventHandler(this.cancelButtonTimer_Tick);
       // 
       // ProgressView
@@ -118,5 +103,4 @@
     private System.Windows.Forms.Button cancelButton;
     private System.Windows.Forms.Panel panel;
-    private System.Windows.Forms.Timer cancelButtonTimer;
   }
 }
Index: stable/HeuristicLab.MainForm.WindowsForms/3.3/MainForms/MainForm.cs
===================================================================
--- stable/HeuristicLab.MainForm.WindowsForms/3.3/MainForms/MainForm.cs	(revision 9931)
+++ stable/HeuristicLab.MainForm.WindowsForms/3.3/MainForms/MainForm.cs	(revision 9933)
@@ -345,4 +345,108 @@
     #endregion
 
+    #region progress views
+    private readonly Dictionary<IContent, IProgress> contentProgressLookup = new Dictionary<IContent, IProgress>();
+    private readonly Dictionary<Control, IProgress> viewProgressLookup = new Dictionary<Control, IProgress>();
+    private readonly List<ProgressView> progressViews = new List<ProgressView>();
+
+    /// <summary>
+    /// Adds a <see cref="ProgressView"/> to the <see cref="ContentView"/>s showing the specified content.
+    /// </summary>
+    public IProgress AddOperationProgressToContent(IContent content, string progressMessage, bool addToObjectGraphObjects = true) {
+      if (InvokeRequired) {
+        IProgress result = (IProgress)Invoke((Func<IContent, string, bool, IProgress>)AddOperationProgressToContent, content, progressMessage, addToObjectGraphObjects);
+        return result;
+      }
+      if (contentProgressLookup.ContainsKey(content))
+        throw new ArgumentException("A progress is already registered for the specified content.", "content");
+
+      var contentViews = views.Keys.OfType<ContentView>();
+      if (!contentViews.Any(v => v.Content == content))
+        throw new ArgumentException("The content is not displayed in a top-level view", "content");
+
+      if (addToObjectGraphObjects) {
+        var containedObjects = content.GetObjectGraphObjects();
+        contentViews = contentViews.Where(v => containedObjects.Contains(v.Content));
+      } else
+        contentViews = contentViews.Where(v => v.Content == content);
+
+      var progress = new Progress(progressMessage, ProgressState.Started);
+      foreach (var contentView in contentViews) {
+        progressViews.Add(new ProgressView(contentView, progress));
+      }
+
+      contentProgressLookup[content] = progress;
+      return progress;
+    }
+
+    /// <summary>
+    /// Adds a <see cref="ProgressView"/> to the specified view.
+    /// </summary>
+    public IProgress AddOperationProgressToView(Control control, string progressMessage) {
+      var progress = new Progress(progressMessage, ProgressState.Started);
+      AddOperationProgressToView(control, progress);
+      return progress;
+    }
+
+    public void AddOperationProgressToView(Control control, IProgress progress) {
+      if (InvokeRequired) {
+        Invoke((Action<Control, IProgress>)AddOperationProgressToView, control, progress);
+        return;
+      }
+      if (control == null) throw new ArgumentNullException("control", "The view must not be null.");
+      if (progress == null) throw new ArgumentNullException("progress", "The progress must not be null.");
+
+      IProgress oldProgress;
+      if (viewProgressLookup.TryGetValue(control, out oldProgress)) {
+        foreach (var progressView in progressViews.Where(v => v.Content == oldProgress).ToList()) {
+          progressView.Dispose();
+          progressViews.Remove(progressView);
+        }
+        viewProgressLookup.Remove(control);
+      }
+
+      progressViews.Add(new ProgressView(control, progress));
+      viewProgressLookup[control] = progress;
+    }
+
+    /// <summary>
+    /// Removes an existing <see cref="ProgressView"/> from the <see cref="ContentView"/>s showing the specified content.
+    /// </summary>
+    public void RemoveOperationProgressFromContent(IContent content, bool finishProgress = true) {
+      if (InvokeRequired) {
+        Invoke((Action<IContent, bool>)RemoveOperationProgressFromContent, content, finishProgress);
+        return;
+      }
+
+      IProgress progress;
+      if (!contentProgressLookup.TryGetValue(content, out progress))
+        throw new ArgumentException("No progress is registered for the specified content.", "content");
+
+      if (finishProgress) progress.Finish();
+      foreach (var progressView in progressViews.Where(v => v.Content == progress).ToList()) {
+        progressView.Dispose();
+        progressViews.Remove(progressView);
+      }
+      contentProgressLookup.Remove(content);
+
+    }
+
+    /// <summary>
+    /// Removes an existing <see cref="ProgressView"/> from the specified view.
+    /// </summary>
+    public void RemoveOperationProgressFromView(Control control, bool finishProgress = true) {
+      IProgress progress;
+      if (!viewProgressLookup.TryGetValue(control, out progress))
+        throw new ArgumentException("No progress is registered for the specified control.", "control");
+
+      if (finishProgress) progress.Finish();
+      foreach (var progressView in progressViews.Where(v => v.Content == progress).ToList()) {
+        progressView.Dispose();
+        progressViews.Remove(progressView);
+      }
+      viewProgressLookup.Remove(control);
+    }
+    #endregion
+
     #region create menu and toolbar
     private void CreateGUI() {
