Index: branches/HeuristicLab.Problems.BioBoost/HeuristicLab.Problems.BioBoost/3.3/Representation/BioBoostCompoundSolution.cs
===================================================================
--- branches/HeuristicLab.Problems.BioBoost/HeuristicLab.Problems.BioBoost/3.3/Representation/BioBoostCompoundSolution.cs	(revision 13071)
+++ branches/HeuristicLab.Problems.BioBoost/HeuristicLab.Problems.BioBoost/3.3/Representation/BioBoostCompoundSolution.cs	(revision 13075)
@@ -136,17 +136,18 @@
     [StorableConstructor]
     private BioBoostCompoundSolution(bool isDeserializing) : base(isDeserializing) { }
-    private BioBoostCompoundSolution(BioBoostCompoundSolution orig, Cloner cloner, bool full = true) : base(orig, cloner) {
+    private BioBoostCompoundSolution(BioBoostCompoundSolution orig, Cloner cloner, bool full = true)
+      : base(orig, cloner) {
       problemDataRef = orig.problemDataRef; // doesn't re-evaluate the solution
       Geometry = orig.Geometry;
       Quality = orig.Quality;
-      Qualities = (DoubleArray) orig.Qualities.Clone();
-      IntValues = orig.IntValues.ToDictionary(kvp => kvp.Key, kvp => (IntArray) kvp.Value.Clone());
+      Qualities = (DoubleArray)orig.Qualities.Clone();
+      IntValues = orig.IntValues.ToDictionary(kvp => kvp.Key, kvp => (IntArray)kvp.Value.Clone());
       if (full) {
-        DoubleValues = orig.DoubleValues.ToDictionary(kvp => kvp.Key, kvp => (DoubleArray) kvp.Value.Clone());
-        StringValues = orig.StringValues.ToDictionary(kvp => kvp.Key, kvp => (StringArray) kvp.Value.Clone());
+        DoubleValues = orig.DoubleValues.ToDictionary(kvp => kvp.Key, kvp => (DoubleArray)kvp.Value.Clone());
+        StringValues = orig.StringValues.ToDictionary(kvp => kvp.Key, kvp => (StringArray)kvp.Value.Clone());
         if (orig.TransportTargets != null)
           TransportTargets = orig.TransportTargets.ToDictionary(kvp => kvp.Key, kvp => (ItemArray<ItemList<IntValue>>)kvp.Value.Clone());
       } else {
-        DoubleValues = orig.DoubleValues.Where(kvp => IsSlimKey(kvp.Key)).ToDictionary(kvp => kvp.Key, kvp => (DoubleArray) kvp.Value.Clone());
+        DoubleValues = orig.DoubleValues.Where(kvp => IsSlimKey(kvp.Key)).ToDictionary(kvp => kvp.Key, kvp => (DoubleArray)kvp.Value.Clone());
         StringValues = new Dictionary<string, StringArray>();
         if (orig.TransportTargets != null)
@@ -171,20 +172,20 @@
       var doubleArray = var.Value as DoubleArray;
       if (doubleArray != null && !DoubleValues.ContainsKey(valueName)) {
-        DoubleValues.Add(valueName, (DoubleArray) doubleArray.Clone());
+        DoubleValues.Add(valueName, (DoubleArray)doubleArray.Clone());
         return true;
       }
       var intArray = var.Value as IntArray;
       if (intArray != null && !IntValues.ContainsKey(valueName)) {
-        IntValues.Add(valueName, (IntArray) intArray.Clone());
+        IntValues.Add(valueName, (IntArray)intArray.Clone());
         return true;
       }
       var stringArray = var.Value as StringArray;
       if (stringArray != null && !StringValues.ContainsKey(valueName)) {
-        StringValues.Add(valueName, (StringArray) stringArray.Clone());
+        StringValues.Add(valueName, (StringArray)stringArray.Clone());
         return true;
       }
       var itemArray = var.Value as ItemArray<ItemList<IntValue>>;
       if (itemArray != null && !TransportTargets.ContainsKey(valueName)) {
-        TransportTargets.Add(valueName, (ItemArray<ItemList<IntValue>>) itemArray.Clone());
+        TransportTargets.Add(valueName, (ItemArray<ItemList<IntValue>>)itemArray.Clone());
       }
       return false;
@@ -198,20 +199,20 @@
           var doubleArray = valueParam.Value as DoubleArray;
           if (doubleArray != null && !DoubleValues.ContainsKey(valueName)) {
-            DoubleValues.Add(valueName, (DoubleArray) doubleArray.Clone());
+            DoubleValues.Add(valueName, (DoubleArray)doubleArray.Clone());
             return true;
           }
           var intArray = valueParam.Value as IntArray;
           if (intArray != null && !IntValues.ContainsKey(valueName)) {
-            IntValues.Add(valueName, (IntArray) intArray.Clone());
+            IntValues.Add(valueName, (IntArray)intArray.Clone());
             return true;
           }
           var stringArray = valueParam.Value as StringArray;
           if (stringArray != null && !StringValues.ContainsKey(valueName)) {
-            StringValues.Add(valueName, (StringArray) stringArray.Clone());
+            StringValues.Add(valueName, (StringArray)stringArray.Clone());
             return true;
           }
           var itemArray = valueParam.Value as ItemArray<ItemList<IntValue>>;
           if (itemArray != null && !TransportTargets.ContainsKey(valueName)) {
-            TransportTargets.Add(valueName, (ItemArray<ItemList<IntValue>>) itemArray.Clone());
+            TransportTargets.Add(valueName, (ItemArray<ItemList<IntValue>>)itemArray.Clone());
             return true;
           }
@@ -221,5 +222,6 @@
     }
 
-    public BioBoostCompoundSolution(IScope scope, BioBoostProblemData problemData) : this() {
+    public BioBoostCompoundSolution(IScope scope, BioBoostProblemData problemData)
+      : this() {
       this.problemDataRef = problemData; // not cloned on purpose
       Geometry = problemData.Geometry; // TODO: maybe clone geometry once?
@@ -228,11 +230,11 @@
       // TotalCost is the quality produced by the aggregate evaluator
       if (scope.Variables.TryGetValue("TotalCost", out qualityVariable)) {
-        Quality = ((DoubleValue) qualityVariable.Value).Value; // TODO: should be read only
+        Quality = ((DoubleValue)qualityVariable.Value).Value; // TODO: should be read only
       } else if (scope.Variables.TryGetValue("Quality", out qualityVariable)) {
-        Quality = ((DoubleValue) qualityVariable.Value).Value; // TODO: should be read only
-      } 
+        Quality = ((DoubleValue)qualityVariable.Value).Value; // TODO: should be read only
+      }
       if (scope.Variables.TryGetValue("QualityCriteria", out qualityVariable)) {
-        Qualities = (DoubleArray) qualityVariable.Value.Clone(); // TODO: should be read only
-      } 
+        Qualities = (DoubleArray)qualityVariable.Value.Clone(); // TODO: should be read only
+      }
       var isUpgradedSolution = scope.Variables.Any(v => v.Name.Contains(LayerDescriptor.AmountsAtSource.FullName));
       foreach (var p in problemData.Products) {
@@ -263,5 +265,5 @@
       if (!Parameters.ContainsKey("Quality"))
         Parameters.Add(new FixedValueParameter<DoubleValue>("Quality", new DoubleValue(double.NaN))); // TODO: use different quality value to indicate that the value is not known?
-      if(!Parameters.ContainsKey("Qualities"))
+      if (!Parameters.ContainsKey("Qualities"))
         Parameters.Add(new ValueParameter<DoubleArray>("Qualities", "The quality criteria of the solution as produced by the evaluator.", new DoubleArray()));
     }
@@ -271,5 +273,5 @@
       if (LocationNames.SequenceEqual(bestSolution.LocationNames)) { // TODO: replace with comparison of problem reference
         Quality = bestSolution.Quality;
-        Qualities = (DoubleArray) bestSolution.Qualities.Clone();
+        Qualities = (DoubleArray)bestSolution.Qualities.Clone();
         IntValues = bestSolution.IntValues.ToDictionary(kvp => kvp.Key, kvp => (IntArray)kvp.Value.Clone());
         DoubleValues = bestSolution.DoubleValues.ToDictionary(kvp => kvp.Key, kvp => (DoubleArray)kvp.Value.Clone());
@@ -503,6 +505,6 @@
       var feedstockUsageBefore =
         utilizations.Zip(
-          (DoubleArray) ((IValueParameter) problemDataRef.FeedstockPotentials[feedstockName + "Potentials"]).Value,
-          (u, p) => u*p).Sum();
+          (DoubleArray)((IValueParameter)problemDataRef.FeedstockPotentials[feedstockName + "Potentials"]).Value,
+          (u, p) => u * p).Sum();
 
       // remove penalized transports
@@ -511,28 +513,28 @@
           kvp => kvp.Key == LayerDescriptor.ExceedingTransportDistancePenalty.NameWithPrefix(feedstockName)).Value;
       var removableSuppliers = feedstockTransportPenaltyLayer
-        .Select((penalty, idx) => new {penalty, idx})
+        .Select((penalty, idx) => new { penalty, idx })
         .Where(pi => pi.penalty > 0)
-        .Select(pi => new List<int> {pi.idx}).ToList();
+        .Select(pi => new List<int> { pi.idx }).ToList();
 
       // remove undersize central plants
       var centralConversion = ProblemDataReference.Conversions[feedstockName].First();
-      var minCentralScalingFactor = centralConversion.MinCapacity/centralConversion.DesignCapacity;
+      var minCentralScalingFactor = centralConversion.MinCapacity / centralConversion.DesignCapacity;
       var centralScalingFactors =
         DoubleValues.First(kvp => kvp.Key == LayerDescriptor.ScalingFactors.NameWithPrefix(intermediateName)).Value;
       removableSuppliers.AddRange(centralScalingFactors
-        .Select((factor, idx) => new {factor, idx})
+        .Select((factor, idx) => new { factor, idx })
         .Where(fi => fi.factor < minCentralScalingFactor)
-        .Select(fi => GetSuppliers(new[] {centralPlantSources, decentralPlantSources}, fi.idx).ToList())
+        .Select(fi => GetSuppliers(new[] { centralPlantSources, decentralPlantSources }, fi.idx).ToList())
         .Where(l => l.Count > 0));
 
       // remove undersize decentral plants
       var decentralConversion = ProblemDataReference.Conversions[intermediateName].First();
-      var minDeCentralScalingFactor = decentralConversion.MinCapacity/decentralConversion.DesignCapacity;
+      var minDeCentralScalingFactor = decentralConversion.MinCapacity / decentralConversion.DesignCapacity;
       var decentralScalingFactors =
         DoubleValues.First(kvp => kvp.Key == LayerDescriptor.ScalingFactors.NameWithPrefix(feedstockName)).Value;
       removableSuppliers.AddRange(decentralScalingFactors
-        .Select((factor, idx) => new {factor, idx})
+        .Select((factor, idx) => new { factor, idx })
         .Where(fi => fi.factor < minDeCentralScalingFactor)
-        .Select(fi => GetSuppliers(new[] {decentralPlantSources}, fi.idx).ToList())
+        .Select(fi => GetSuppliers(new[] { decentralPlantSources }, fi.idx).ToList())
         .Where(l => l.Count > 0));
 
@@ -549,5 +551,5 @@
         EvaluateAndUpdateAllResults();
         if (Quality < oldQuality) {
-          for (int i = 0; i<utilizations.Length; i++) utilizations[i] = oldUtilizations[i];
+          for (int i = 0; i < utilizations.Length; i++) utilizations[i] = oldUtilizations[i];
           DoubleValues.Remove(LayerDescriptor.Utilizations.NameWithPrefix(feedstockName));
           DoubleValues.Add(LayerDescriptor.Utilizations.NameWithPrefix(feedstockName), utilizations);
@@ -555,6 +557,6 @@
           successes++;
         }
-        if (k++ > lastK + removableSuppliers.Count/20 && logger != null) {
-          logger.Write("{0}%...", k*100/removableSuppliers.Count);
+        if (k++ > lastK + removableSuppliers.Count / 20 && logger != null) {
+          logger.Write("{0}%...", k * 100 / removableSuppliers.Count);
           lastK = k;
         }
@@ -564,32 +566,31 @@
 
       var feedstockUsageAfter =
-        utilizations.Zip((DoubleArray) ((IValueParameter) problemDataRef.FeedstockPotentials[feedstockName + "Potentials"]).Value,
-          (u, p) => u*p).Sum();
-      var utilizationFactor = feedstockUsageAfter/feedstockUsageBefore;
+        utilizations.Zip((DoubleArray)((IValueParameter)problemDataRef.FeedstockPotentials[feedstockName + "Potentials"]).Value,
+          (u, p) => u * p).Sum();
+      var utilizationFactor = feedstockUsageAfter / feedstockUsageBefore;
       return utilizationFactor;
     }
 
     public static IEnumerable<int> GetSuppliers(IEnumerable<IDictionary<int, int[]>> suppliers, int i) {
-      throw new NotImplementedException();  // waiting for source for DictionaryExtensions
-      //       var lists = suppliers.ToList();
-//       switch (lists.Count) {
-//         case 0: {
-//           yield break;
-//         }
-//         case 1: {
-//           foreach (var j in lists[0].ElementAtOrDefault(i, new int[0]))
-//             yield return j;
-//           break;
-//         } 
-//         default: {
-//           foreach (
-//             var x in lists[0].ApplyAt(i,
-//                 v => v.Select(j => GetSuppliers(lists.Skip(1), j))
-//                       .Aggregate(Enumerable.Empty<int>(), (l1, l2) => l1.Concat(l2)),
-//                 () => new int[0]))
-//             yield return x;
-//           break;
-//         }
-//       }
+      var lists = suppliers.ToList();
+      switch (lists.Count) {
+        case 0: {
+            yield break;
+          }
+        case 1: {
+            foreach (var j in lists[0].ElementAtOrDefault(i, new int[0]))
+              yield return j;
+            break;
+          }
+        default: {
+            foreach (
+              var x in lists[0].ApplyAt(i,
+                  v => v.Select(j => GetSuppliers(lists.Skip(1), j))
+                        .Aggregate(Enumerable.Empty<int>(), (l1, l2) => l1.Concat(l2)),
+                  () => new int[0]))
+              yield return x;
+            break;
+          }
+      }
     }
 
