Index: /trunk/sources/HeuristicLab.Encodings.ScheduleEncoding.Views/3.3/JobView.Designer.cs
===================================================================
--- /trunk/sources/HeuristicLab.Encodings.ScheduleEncoding.Views/3.3/JobView.Designer.cs	(revision 10432)
+++ /trunk/sources/HeuristicLab.Encodings.ScheduleEncoding.Views/3.3/JobView.Designer.cs	(revision 10433)
@@ -80,5 +80,5 @@
       this.dueDateLabel.Name = "dueDateLabel";
       this.dueDateLabel.Size = new System.Drawing.Size(56, 13);
-      this.dueDateLabel.TabIndex = 0;
+      this.dueDateLabel.TabIndex = 2;
       this.dueDateLabel.Text = "Due Date:";
       // 
@@ -90,5 +90,5 @@
       this.dueDateTextBox.Name = "dueDateTextBox";
       this.dueDateTextBox.Size = new System.Drawing.Size(451, 20);
-      this.dueDateTextBox.TabIndex = 1;
+      this.dueDateTextBox.TabIndex = 3;
       this.dueDateTextBox.Validating += new System.ComponentModel.CancelEventHandler(this.dueDateTextBox_Validating);
       // 
@@ -101,5 +101,5 @@
       this.tasksGroupBox.Name = "tasksGroupBox";
       this.tasksGroupBox.Size = new System.Drawing.Size(510, 214);
-      this.tasksGroupBox.TabIndex = 2;
+      this.tasksGroupBox.TabIndex = 4;
       this.tasksGroupBox.TabStop = false;
       this.tasksGroupBox.Text = "Tasks";
Index: /trunk/sources/HeuristicLab.Encodings.ScheduleEncoding.Views/3.3/TaskView.Designer.cs
===================================================================
--- /trunk/sources/HeuristicLab.Encodings.ScheduleEncoding.Views/3.3/TaskView.Designer.cs	(revision 10432)
+++ /trunk/sources/HeuristicLab.Encodings.ScheduleEncoding.Views/3.3/TaskView.Designer.cs	(revision 10433)
@@ -83,5 +83,5 @@
       this.resourceNrLabel.Name = "resourceNrLabel";
       this.resourceNrLabel.Size = new System.Drawing.Size(70, 13);
-      this.resourceNrLabel.TabIndex = 0;
+      this.resourceNrLabel.TabIndex = 2;
       this.resourceNrLabel.Text = "Resource Nr:";
       // 
@@ -93,5 +93,5 @@
       this.resourceNrTextBox.Name = "resourceNrTextBox";
       this.resourceNrTextBox.Size = new System.Drawing.Size(437, 20);
-      this.resourceNrTextBox.TabIndex = 1;
+      this.resourceNrTextBox.TabIndex = 3;
       this.resourceNrTextBox.Validating += new System.ComponentModel.CancelEventHandler(this.resourceNrTextBox_Validating);
       // 
@@ -106,5 +106,5 @@
       this.jobNrLabel.Name = "jobNrLabel";
       this.jobNrLabel.Size = new System.Drawing.Size(41, 13);
-      this.jobNrLabel.TabIndex = 0;
+      this.jobNrLabel.TabIndex = 4;
       this.jobNrLabel.Text = "Job Nr:";
       // 
@@ -116,5 +116,5 @@
       this.jobNrTextBox.Name = "jobNrTextBox";
       this.jobNrTextBox.Size = new System.Drawing.Size(437, 20);
-      this.jobNrTextBox.TabIndex = 1;
+      this.jobNrTextBox.TabIndex = 5;
       this.jobNrTextBox.Validating += new System.ComponentModel.CancelEventHandler(this.jobNrTextBox_Validating);
       // 
@@ -125,5 +125,5 @@
       this.durationLabel.Name = "durationLabel";
       this.durationLabel.Size = new System.Drawing.Size(50, 13);
-      this.durationLabel.TabIndex = 0;
+      this.durationLabel.TabIndex = 6;
       this.durationLabel.Text = "Duration:";
       // 
@@ -135,5 +135,5 @@
       this.durationTextBox.Name = "durationTextBox";
       this.durationTextBox.Size = new System.Drawing.Size(437, 20);
-      this.durationTextBox.TabIndex = 1;
+      this.durationTextBox.TabIndex = 7;
       this.durationTextBox.Validating += new System.ComponentModel.CancelEventHandler(this.durationTextBox_Validating);
       // 
Index: /trunk/sources/HeuristicLab.Encodings.ScheduleEncoding/3.3/ScheduleEncoding/Job.cs
===================================================================
--- /trunk/sources/HeuristicLab.Encodings.ScheduleEncoding/3.3/ScheduleEncoding/Job.cs	(revision 10432)
+++ /trunk/sources/HeuristicLab.Encodings.ScheduleEncoding/3.3/ScheduleEncoding/Job.cs	(revision 10433)
@@ -20,6 +20,8 @@
 #endregion
 
+using System;
 using System.ComponentModel;
 using System.Text;
+using HeuristicLab.Collections;
 using HeuristicLab.Common;
 using HeuristicLab.Core;
@@ -38,5 +40,8 @@
         bool changed = dueDate != value;
         dueDate = value;
-        if (changed) OnPropertyChanged("DueDate");
+        if (changed) {
+          OnPropertyChanged("DueDate");
+          OnToStringChanged();
+        }
       }
     }
@@ -49,5 +54,8 @@
         bool changed = index != value;
         index = value;
-        if (changed) OnPropertyChanged("Index");
+        if (changed) {
+          OnPropertyChanged("Index");
+          OnToStringChanged();
+        }
       }
     }
@@ -71,4 +79,5 @@
       this.Index = original.Index;
       this.Tasks = cloner.Clone(original.Tasks);
+      RegisterEventHandlers();
     }
     public Job() : this(-1, double.MaxValue) { }
@@ -78,8 +87,46 @@
       Index = index;
       Tasks = new ItemList<Task>();
+      RegisterEventHandlers();
     }
 
     public override IDeepCloneable Clone(Cloner cloner) {
       return new Job(this, cloner);
+    }
+
+    [StorableHook(HookType.AfterDeserialization)]
+    private void AfterDeserialization() {
+      RegisterEventHandlers();
+    }
+
+    private void RegisterEventHandlers() {
+      Tasks.ItemsAdded += TasksOnItemsChanged;
+      Tasks.ItemsRemoved += TasksOnItemsChanged;
+      Tasks.ItemsReplaced += TasksOnItemsChanged;
+      Tasks.CollectionReset += TasksOnItemsChanged;
+      foreach (var task in Tasks) {
+        task.PropertyChanged += TaskOnPropertyChanged;
+        task.ToStringChanged += TaskOnToStringChanged;
+      }
+    }
+
+    private void TasksOnItemsChanged(object sender, CollectionItemsChangedEventArgs<IndexedItem<Task>> e) {
+      foreach (var task in e.OldItems) {
+        task.Value.PropertyChanged -= TaskOnPropertyChanged;
+        task.Value.ToStringChanged -= TaskOnToStringChanged;
+      }
+      foreach (var task in e.Items) {
+        task.Value.PropertyChanged += TaskOnPropertyChanged;
+        task.Value.ToStringChanged += TaskOnToStringChanged;
+      }
+      OnTasksChanged();
+      OnToStringChanged();
+    }
+
+    private void TaskOnPropertyChanged(object sender, EventArgs e) {
+      OnTasksChanged();
+    }
+
+    private void TaskOnToStringChanged(object sender, EventArgs e) {
+      OnToStringChanged();
     }
 
@@ -100,4 +147,10 @@
     }
 
+    public event EventHandler TasksChanged;
+    protected virtual void OnTasksChanged() {
+      var handler = TasksChanged;
+      if (handler != null) handler(this, EventArgs.Empty);
+    }
+
     public event PropertyChangedEventHandler PropertyChanged;
     protected virtual void OnPropertyChanged(string propertyName) {
Index: /trunk/sources/HeuristicLab.Encodings.ScheduleEncoding/3.3/ScheduleEncoding/Task.cs
===================================================================
--- /trunk/sources/HeuristicLab.Encodings.ScheduleEncoding/3.3/ScheduleEncoding/Task.cs	(revision 10432)
+++ /trunk/sources/HeuristicLab.Encodings.ScheduleEncoding/3.3/ScheduleEncoding/Task.cs	(revision 10433)
@@ -38,5 +38,8 @@
         bool changed = taskNr != value;
         taskNr = value;
-        if (changed) OnPropertyChanged("TaskNr");
+        if (changed) {
+          OnPropertyChanged("TaskNr");
+          OnToStringChanged();
+        }
       }
     }
@@ -48,5 +51,8 @@
         bool changed = resourceNr != value;
         resourceNr = value;
-        if (changed) OnPropertyChanged("ResourceNr");
+        if (changed) {
+          OnPropertyChanged("ResourceNr");
+          OnToStringChanged();
+        }
       }
     }
@@ -115,23 +121,4 @@
     }
 
-    public override bool Equals(object obj) {
-      if (obj.GetType() == typeof(Task))
-        return AreEqual(this, obj as Task);
-      else
-        return false;
-    }
-
-    public override int GetHashCode() {
-      return TaskNr ^ JobNr;
-    }
-
-    public static bool AreEqual(Task task1, Task task2) {
-      return (task1.Duration == task2.Duration &&
-        task1.IsScheduled == task2.IsScheduled &&
-        task1.JobNr == task2.JobNr &&
-        task1.ResourceNr == task2.ResourceNr &&
-        task1.TaskNr == task2.TaskNr);
-    }
-
     public event PropertyChangedEventHandler PropertyChanged;
     protected virtual void OnPropertyChanged(string propertyName) {
Index: /trunk/sources/HeuristicLab.Problems.Scheduling.Views/3.3/JobShopSchedulingProblemView.cs
===================================================================
--- /trunk/sources/HeuristicLab.Problems.Scheduling.Views/3.3/JobShopSchedulingProblemView.cs	(revision 10432)
+++ /trunk/sources/HeuristicLab.Problems.Scheduling.Views/3.3/JobShopSchedulingProblemView.cs	(revision 10433)
@@ -20,5 +20,8 @@
 #endregion
 
+using System;
 using System.Windows.Forms;
+using HeuristicLab.Collections;
+using HeuristicLab.Encodings.ScheduleEncoding;
 using HeuristicLab.MainForm;
 using HeuristicLab.Optimization.Views;
@@ -43,32 +46,60 @@
     protected override void OnContentChanged() {
       base.OnContentChanged();
-      if (Content == null) {
-        ganttChart.Reset();
-      } else {
-        FillGanttChart(Content);
-      }
+      FillGanttChart();
     }
 
     protected override void DeregisterContentEvents() {
-      Content.JobDataParameter.ValueChanged -= JobDataParameter_ValueChanged;
+      Content.JobDataParameter.ValueChanged -= JobDataParameterOnValueChanged;
+      Content.JobData.ItemsAdded -= JobsOnChanged;
+      Content.JobData.ItemsRemoved -= JobsOnChanged;
+      Content.JobData.ItemsReplaced -= JobsOnChanged;
+      Content.JobData.CollectionReset -= JobsOnChanged;
+      foreach (var job in Content.JobData) {
+        job.TasksChanged -= JobOnTasksChanged;
+      }
       base.DeregisterContentEvents();
     }
     protected override void RegisterContentEvents() {
       base.RegisterContentEvents();
-      Content.JobDataParameter.ValueChanged += JobDataParameter_ValueChanged;
-    }
-
-    void JobDataParameter_ValueChanged(object sender, System.EventArgs e) {
-      if (Content != null) {
-        FillGanttChart(Content);
+      Content.JobDataParameter.ValueChanged += JobDataParameterOnValueChanged;
+      Content.JobData.ItemsAdded += JobsOnChanged;
+      Content.JobData.ItemsRemoved += JobsOnChanged;
+      Content.JobData.ItemsReplaced += JobsOnChanged;
+      Content.JobData.CollectionReset += JobsOnChanged;
+      foreach (var job in Content.JobData) {
+        job.TasksChanged += JobOnTasksChanged;
       }
     }
 
-    private void FillGanttChart(JobShopSchedulingProblem content) {
+    private void JobsOnChanged(object sender, CollectionItemsChangedEventArgs<IndexedItem<Job>> e) {
+      foreach (var job in e.OldItems)
+        job.Value.TasksChanged -= JobOnTasksChanged;
+      foreach (var job in e.Items)
+        job.Value.TasksChanged += JobOnTasksChanged;
+      FillGanttChart();
+    }
+
+    private void JobDataParameterOnValueChanged(object sender, EventArgs e) {
+      Content.JobData.ItemsAdded += JobsOnChanged;
+      Content.JobData.ItemsRemoved += JobsOnChanged;
+      Content.JobData.ItemsReplaced += JobsOnChanged;
+      Content.JobData.CollectionReset += JobsOnChanged;
+      foreach (var job in Content.JobData) {
+        job.TasksChanged += JobOnTasksChanged;
+      }
+      FillGanttChart();
+    }
+
+    private void JobOnTasksChanged(object sender, EventArgs e) {
+      FillGanttChart();
+    }
+
+    private void FillGanttChart() {
       ganttChart.Reset();
+      if (Content == null) return;
       int jobCount = 0;
-      foreach (var j in content.JobData) {
+      foreach (var j in Content.JobData) {
         double lastEndTime = 0;
-        foreach (var t in content.JobData[jobCount].Tasks) {
+        foreach (var t in Content.JobData[jobCount].Tasks) {
           int categoryNr = t.JobNr;
           string categoryName = "Job" + categoryNr;
@@ -78,5 +109,5 @@
             lastEndTime + 1,
             lastEndTime + t.Duration,
-            "Job" + t.JobNr + " - " + "Task#" + t.TaskNr.ToString());
+            "Job" + t.JobNr + " - " + "Task#" + t.TaskNr);
           lastEndTime += t.Duration;
         }
