Index: /trunk/sources/HeuristicLab.Algorithms.OffspringSelectionGeneticAlgorithm/3.3/SASEGASAMainLoop.cs
===================================================================
--- /trunk/sources/HeuristicLab.Algorithms.OffspringSelectionGeneticAlgorithm/3.3/SASEGASAMainLoop.cs	(revision 3488)
+++ /trunk/sources/HeuristicLab.Algorithms.OffspringSelectionGeneticAlgorithm/3.3/SASEGASAMainLoop.cs	(revision 3489)
@@ -155,12 +155,20 @@
       QualityDifferenceCalculator qualityDifferenceCalculator1 = new QualityDifferenceCalculator();
       ResultsCollector resultsCollector = new ResultsCollector();
+      Assigner fixedReunificationStepConditionInitializer = new Assigner();
       UniformSubScopesProcessor ussp1 = new UniformSubScopesProcessor();
+      // MAINLOOP
       OffspringSelectionGeneticAlgorithmMainLoop mainLoop = new OffspringSelectionGeneticAlgorithmMainLoop();
-      UniformSubScopesProcessor ussp2 = new UniformSubScopesProcessor();
+      // MAINLOOP
       Comparator sasegasaGenVillageGenComparator = new Comparator();
       ConditionalBranch sasegasaGenerationsUpdateBranch = new ConditionalBranch();
       Assigner sasegasaGenerationsUpdater = new Assigner();
-      ConditionalBranch villageMaximumGenerationsConditionalBranch = new ConditionalBranch();
+      ConditionalBranch villageMaximumGenerationsConditionalBranch1 = new ConditionalBranch();
+      Assigner fixedReunificationStepConditionUpdater = new Assigner();
+      ResultsCollector sasegasaGenerationsCollector = new ResultsCollector();
+      UniformSubScopesProcessor ussp2 = new UniformSubScopesProcessor();
+      ConditionalBranch villageMaximumGenerationsConditionalBranch2 = new ConditionalBranch();
+      Assigner villageMaximumGenerationsToGenerationsAssigner = new Assigner();
       IntCounter villageMaximumGenerationsCounter = new IntCounter();
+      DataTableValuesCollector selPressValuesCollector2 = new DataTableValuesCollector();
       Comparator villageCountComparator = new Comparator();
       ConditionalBranch villageTerminationCondition0 = new ConditionalBranch();
@@ -172,5 +180,4 @@
       BestAverageWorstQualityCalculator bestAverageWorstQualityCalculator3 = new BestAverageWorstQualityCalculator();
       DataTableValuesCollector dataTableValuesCollector2 = new DataTableValuesCollector();
-      DataTableValuesCollector selPressValuesCollector2 = new DataTableValuesCollector();
       QualityDifferenceCalculator qualityDifferenceCalculator2 = new QualityDifferenceCalculator();
       ConditionalBranch villagesTerminationCondition = new ConditionalBranch();
@@ -240,4 +247,7 @@
       resultsCollector.CollectedValues.Add(new SubScopesLookupParameter<ResultCollection>("VillageResults", "Result set for each village"));
       resultsCollector.ResultsParameter.ActualName = ResultsParameter.Name;
+
+      fixedReunificationStepConditionInitializer.LeftSideParameter.ActualName = "PerformFixedReunification";
+      fixedReunificationStepConditionInitializer.RightSideParameter.Value = new BoolValue(false);
 
       mainLoop.BestKnownQualityParameter.ActualName = BestKnownQualityParameter.Name;
@@ -273,11 +283,25 @@
       sasegasaGenerationsUpdater.RightSideParameter.ActualName = "Generations";
 
-      // check if the village has terminated due to reaching maximum generations (in that case we need to increase maximum generations by the migration interval)
-      villageMaximumGenerationsConditionalBranch.ConditionParameter.ActualName = "TerminateMaximumGenerations";
-
-      // if the village terminated because of maximum generations (inter-migration period) its maximum generations are updated
+      // check if the village has terminated due to reaching maximum generations (in that case we need to increase in each village the maximum generations by the migration interval)
+      villageMaximumGenerationsConditionalBranch1.ConditionParameter.ActualName = "TerminateMaximumGenerations";
+
+      fixedReunificationStepConditionUpdater.LeftSideParameter.ActualName = "PerformFixedReunification";
+      fixedReunificationStepConditionUpdater.RightSideParameter.Value = new BoolValue(true);
+
+      sasegasaGenerationsCollector.CollectedValues.Add(new LookupParameter<IntValue>("Generations", null, "SASEGASAGenerations"));
+
+      villageMaximumGenerationsConditionalBranch2.ConditionParameter.ActualName = "PerformFixedReunification";
+
+      // if the village terminated because of maximum generations first set the maxgen of a village back to its generation
+      villageMaximumGenerationsToGenerationsAssigner.LeftSideParameter.ActualName = "VillageMaximumGenerations";
+      villageMaximumGenerationsToGenerationsAssigner.RightSideParameter.ActualName = "Generations";
+
+      // if the village terminated because of maximum generations and then increase the maximum generations by the fixed migration interval
       villageMaximumGenerationsCounter.ValueParameter.ActualName = "VillageMaximumGenerations";
       villageMaximumGenerationsCounter.Increment = null;
       villageMaximumGenerationsCounter.IncrementParameter.ActualName = "MigrationInterval";
+
+      selPressValuesCollector2.CollectedValues.Add(new SubScopesLookupParameter<DoubleValue>("Selection Pressure Village", null, "SelectionPressure"));
+      selPressValuesCollector2.DataTableParameter.ActualName = "VillagesSelectionPressures";
 
       // if there's just one island left and we're getting to this point SASEGASA terminates
@@ -321,7 +345,4 @@
       dataTableValuesCollector2.DataTableParameter.ActualName = "BestQualities";
 
-      selPressValuesCollector2.CollectedValues.Add(new SubScopesLookupParameter<DoubleValue>("Selection Pressure Village", null, "SelectionPressure"));
-      selPressValuesCollector2.DataTableParameter.ActualName = "VillagesSelectionPressures";
-
       qualityDifferenceCalculator2.AbsoluteDifferenceParameter.ActualName = "AbsoluteDifferenceBestKnownToBest";
       qualityDifferenceCalculator2.FirstQualityParameter.ActualName = BestKnownQualityParameter.Name;
@@ -330,5 +351,5 @@
 
       villagesTerminationCondition.ConditionParameter.ActualName = "TerminateVillages";
-      villageMaximumGenerationsConditionalBranch.ConditionParameter.ActualName = "TerminateMaximumGenerations";
+      villageMaximumGenerationsConditionalBranch1.ConditionParameter.ActualName = "TerminateMaximumGenerations";
       #endregion
 
@@ -348,18 +369,25 @@
       selPressValuesCollector1.Successor = qualityDifferenceCalculator1;
       qualityDifferenceCalculator1.Successor = resultsCollector;
-      resultsCollector.Successor = ussp1;
+      resultsCollector.Successor = fixedReunificationStepConditionInitializer;
+      fixedReunificationStepConditionInitializer.Successor = ussp1;
       ussp1.Operator = mainLoop;
-      ussp1.Successor = ussp2;
+      ussp1.Successor = sasegasaGenerationsCollector;
       mainLoop.Successor = sasegasaGenVillageGenComparator;
       sasegasaGenVillageGenComparator.Successor = sasegasaGenerationsUpdateBranch;
       sasegasaGenerationsUpdateBranch.TrueBranch = sasegasaGenerationsUpdater;
       sasegasaGenerationsUpdateBranch.FalseBranch = null;
-      sasegasaGenerationsUpdateBranch.Successor = null;
-      ussp2.Operator = villageMaximumGenerationsConditionalBranch;
-      ussp2.Successor = villageCountComparator;
-      villageMaximumGenerationsConditionalBranch.TrueBranch = villageMaximumGenerationsCounter;
-      villageMaximumGenerationsConditionalBranch.FalseBranch = null;
-      villageMaximumGenerationsConditionalBranch.Successor = null;
+      sasegasaGenerationsUpdateBranch.Successor = villageMaximumGenerationsConditionalBranch1;
+      villageMaximumGenerationsConditionalBranch1.TrueBranch = fixedReunificationStepConditionUpdater;
+      villageMaximumGenerationsConditionalBranch1.FalseBranch = null;
+      villageMaximumGenerationsConditionalBranch1.Successor = null;
+      sasegasaGenerationsCollector.Successor = ussp2;
+      ussp2.Operator = villageMaximumGenerationsConditionalBranch2;
+      ussp2.Successor = selPressValuesCollector2;
+      villageMaximumGenerationsConditionalBranch2.TrueBranch = villageMaximumGenerationsToGenerationsAssigner;
+      villageMaximumGenerationsConditionalBranch2.FalseBranch = null;
+      villageMaximumGenerationsConditionalBranch2.Successor = null;
+      villageMaximumGenerationsToGenerationsAssigner.Successor = villageMaximumGenerationsCounter;
       villageMaximumGenerationsCounter.Successor = null;
+      selPressValuesCollector2.Successor = villageCountComparator;
       villageCountComparator.Successor = villageTerminationCondition0;
       villageTerminationCondition0.TrueBranch = null;
@@ -372,11 +400,10 @@
       bestQualityMemorizer3.Successor = bestAverageWorstQualityCalculator3;
       bestAverageWorstQualityCalculator3.Successor = dataTableValuesCollector2;
-      dataTableValuesCollector2.Successor = selPressValuesCollector2;
-      selPressValuesCollector2.Successor = qualityDifferenceCalculator2;
+      dataTableValuesCollector2.Successor = qualityDifferenceCalculator2;
       qualityDifferenceCalculator2.Successor = villagesTerminationCondition;
       villagesTerminationCondition.FalseBranch = maximumGenerationsTerminationCondition;
       villagesTerminationCondition.TrueBranch = null;
       villagesTerminationCondition.Successor = null;
-      maximumGenerationsTerminationCondition.FalseBranch = ussp1;
+      maximumGenerationsTerminationCondition.FalseBranch = fixedReunificationStepConditionInitializer;
       maximumGenerationsTerminationCondition.TrueBranch = null;
       maximumGenerationsTerminationCondition.Successor = null;
Index: /trunk/sources/HeuristicLab.Analysis/3.3/DataTableValuesCollector.cs
===================================================================
--- /trunk/sources/HeuristicLab.Analysis/3.3/DataTableValuesCollector.cs	(revision 3488)
+++ /trunk/sources/HeuristicLab.Analysis/3.3/DataTableValuesCollector.cs	(revision 3489)
@@ -21,4 +21,5 @@
 
 using System;
+using System.Collections.Generic;
 using HeuristicLab.Common;
 using HeuristicLab.Core;
@@ -53,41 +54,29 @@
       foreach (IParameter param in CollectedValues) {
         if (param.ActualValue is DoubleValue) {
-          DoubleValue data = param.ActualValue as DoubleValue;
-          DataRow row;
-          table.Rows.TryGetValue(param.Name, out row);
-          if (row == null) {
-            row = new DataRow(param.Name, param.Description);
-            row.Values.Add(data.Value);
-            table.Rows.Add(row);
-          } else {
-            row.Values.Add(data.Value);
-          }
-        } else if (param.ActualValue is ItemArray<DoubleValue>) {
-          ItemArray<DoubleValue> dataArray = param.ActualValue as ItemArray<DoubleValue>;
-          DataRow row;
-          for (int i = 0; i < dataArray.Length; i++) {
-            table.Rows.TryGetValue(param.Name + i.ToString(), out row);
-            if (row == null) {
-              row = new DataRow(param.Name + i.ToString(), param.Description);
-              row.Values.Add(dataArray[i].Value);
-              table.Rows.Add(row);
-            } else {
-              row.Values.Add(dataArray[i].Value);
-            }
+          AddValue(table, (param.ActualValue as DoubleValue).Value, param.Name, param.Description);
+        } else if (param.ActualValue is IEnumerable<DoubleValue>) {
+          int counter = 0;
+          foreach (DoubleValue data in (param.ActualValue as IEnumerable<DoubleValue>)) {
+            AddValue(table, data.Value, param.Name + counter.ToString(), param.Description);
+            counter++;
           }
         } else {
-          DataRow row;
-          table.Rows.TryGetValue(param.Name, out row);
-          if (row == null) {
-            row = new DataRow(param.Name, param.Description);
-            row.Values.Add(double.NaN);
-            table.Rows.Add(row);
-          } else {
-            row.Values.Add(double.NaN);
-          }
+          AddValue(table, double.NaN, param.Name, param.Description);
         }
       }
       return base.Apply();
     }
+
+    private void AddValue(DataTable table, double data, string name, string description) {
+      DataRow row;
+      table.Rows.TryGetValue(name, out row);
+      if (row == null) {
+        row = new DataRow(name, description);
+        row.Values.Add(data);
+        table.Rows.Add(row);
+      } else {
+        row.Values.Add(data);
+      }
+    }
   }
 }
Index: /trunk/sources/HeuristicLab.Optimization.Operators/3.3/SASEGASAReunificator.cs
===================================================================
--- /trunk/sources/HeuristicLab.Optimization.Operators/3.3/SASEGASAReunificator.cs	(revision 3488)
+++ /trunk/sources/HeuristicLab.Optimization.Operators/3.3/SASEGASAReunificator.cs	(revision 3489)
@@ -34,7 +34,7 @@
   /// scopes by 1 and uniformly partitions the sub sub scopes again, maintaining the order.
   /// </summary>
-  [Item("SASEGASAReunificator", "This operator merges the villages in a migration phase and redistributes the individuals. It is implemented as described in Affenzeller, M. et al. 2009. Genetic Algorithms and Genetic Programming - Modern Concepts and Practical Applications, CRC Press.")]
+  [Item("SASEGASAReunificator", "This operator merges the villages (sub-scopes) and redistributes the individuals. It is implemented as described in Affenzeller, M. et al. 2009. Genetic Algorithms and Genetic Programming - Modern Concepts and Practical Applications, CRC Press.")]
   [StorableClass]
-  public class SASEGASAReunificator : SingleSuccessorOperator, IMigrator {
+  public class SASEGASAReunificator : SingleSuccessorOperator {
 
     public LookupParameter<IntValue> VillageCountParameter {
@@ -78,5 +78,5 @@
       }
 
-      // add remaining sub-sub-scopes to last sub-scope
+      // add remaining individuals to last village
       scope.SubScopes[scope.SubScopes.Count - 1].SubScopes.AddRange(population);
       population.Clear();
Index: /trunk/sources/HeuristicLab.Selection/3.3/OffspringSelector.cs
===================================================================
--- /trunk/sources/HeuristicLab.Selection/3.3/OffspringSelector.cs	(revision 3488)
+++ /trunk/sources/HeuristicLab.Selection/3.3/OffspringSelector.cs	(revision 3489)
@@ -113,12 +113,10 @@
       winners.AddRange(offspring);
       offspring = children.SubScopes[0].SubScopes; // the losers
+      losersCount += offspring.Count;
       while (offspring.Count > 0 && ((1 - successRatio) * populationSize > luckyLosers.Count ||
             selectionPressure.Value >= maxSelPress)) {
         luckyLosers.Add(offspring[0]);
-        losersCount++;
         offspring.RemoveAt(0);
       }
-      losersCount += offspring.Count;
-      children.SubScopes.Clear();
 
       // calculate actual selection pressure and success ratio
@@ -140,4 +138,5 @@
       } else {
         // enough children generated
+        children.SubScopes.Clear();
         while (children.SubScopes.Count < populationSize) {
           if (winners.Count > 0) {
