Index: /branches/2521_ProblemRefactoring/HeuristicLab.Data/3.3/BoolArray.cs
===================================================================
--- /branches/2521_ProblemRefactoring/HeuristicLab.Data/3.3/BoolArray.cs	(revision 17252)
+++ /branches/2521_ProblemRefactoring/HeuristicLab.Data/3.3/BoolArray.cs	(revision 17253)
@@ -21,7 +21,7 @@
 
 using System.Text;
+using HEAL.Attic;
 using HeuristicLab.Common;
 using HeuristicLab.Core;
-using HEAL.Attic;
 
 namespace HeuristicLab.Data {
@@ -36,5 +36,5 @@
     public BoolArray() : base() { }
     public BoolArray(int length) : base(length) { }
-    public BoolArray(bool[] elements) : base(elements) { }
+    public BoolArray(bool[] elements, bool @readonly = false) : base(elements, @readonly) { }
 
     public override IDeepCloneable Clone(Cloner cloner) {
@@ -67,4 +67,8 @@
       }
     }
+
+    public new BoolArray AsReadOnly() {
+      return (BoolArray)base.AsReadOnly();
+    }
   }
 }
Index: /branches/2521_ProblemRefactoring/HeuristicLab.Data/3.3/BoolMatrix.cs
===================================================================
--- /branches/2521_ProblemRefactoring/HeuristicLab.Data/3.3/BoolMatrix.cs	(revision 17252)
+++ /branches/2521_ProblemRefactoring/HeuristicLab.Data/3.3/BoolMatrix.cs	(revision 17253)
@@ -22,7 +22,7 @@
 using System.Collections.Generic;
 using System.Text;
+using HEAL.Attic;
 using HeuristicLab.Common;
 using HeuristicLab.Core;
-using HEAL.Attic;
 
 namespace HeuristicLab.Data {
@@ -39,7 +39,7 @@
     public BoolMatrix(int rows, int columns, IEnumerable<string> columnNames) : base(rows, columns, columnNames) { }
     public BoolMatrix(int rows, int columns, IEnumerable<string> columnNames, IEnumerable<string> rowNames) : base(rows, columns, columnNames, rowNames) { }
-    public BoolMatrix(bool[,] elements) : base(elements) { }
-    public BoolMatrix(bool[,] elements, IEnumerable<string> columnNames) : base(elements, columnNames) { }
-    public BoolMatrix(bool[,] elements, IEnumerable<string> columnNames, IEnumerable<string> rowNames) : base(elements, columnNames, rowNames) { }
+    public BoolMatrix(bool[,] elements, bool @readonly = false) : base(elements, @readonly) { }
+    public BoolMatrix(bool[,] elements, IEnumerable<string> columnNames, bool @readonly = false) : base(elements, columnNames, @readonly) { }
+    public BoolMatrix(bool[,] elements, IEnumerable<string> columnNames, IEnumerable<string> rowNames, bool @readonly = false) : base(elements, columnNames, rowNames, @readonly) { }
 
     public override IDeepCloneable Clone(Cloner cloner) {
@@ -73,4 +73,8 @@
     }
 
+    public new BoolMatrix AsReadOnly() {
+      return (BoolMatrix)base.AsReadOnly();
+    }
+
     #region IStringConvertibleMatrix Members
     int IStringConvertibleMatrix.Rows {
Index: /branches/2521_ProblemRefactoring/HeuristicLab.Data/3.3/BoolValue.cs
===================================================================
--- /branches/2521_ProblemRefactoring/HeuristicLab.Data/3.3/BoolValue.cs	(revision 17252)
+++ /branches/2521_ProblemRefactoring/HeuristicLab.Data/3.3/BoolValue.cs	(revision 17253)
@@ -23,7 +23,7 @@
 using System.Drawing;
 using System.Text;
+using HEAL.Attic;
 using HeuristicLab.Common;
 using HeuristicLab.Core;
-using HEAL.Attic;
 
 namespace HeuristicLab.Data {
@@ -41,5 +41,5 @@
     }
     public BoolValue() : base() { }
-    public BoolValue(bool value) : base(value) { }
+    public BoolValue(bool value, bool @readonly = false) : base(value, @readonly) { }
 
     public override IDeepCloneable Clone(Cloner cloner) {
@@ -81,4 +81,8 @@
     }
 
+    public new BoolValue AsReadOnly() {
+      return (BoolValue)base.AsReadOnly();
+    }
+
     #region IStringConvertibleValue Members
     bool IStringConvertibleValue.Validate(string value, out string errorMessage) {
Index: /branches/2521_ProblemRefactoring/HeuristicLab.Data/3.3/DoubleArray.cs
===================================================================
--- /branches/2521_ProblemRefactoring/HeuristicLab.Data/3.3/DoubleArray.cs	(revision 17252)
+++ /branches/2521_ProblemRefactoring/HeuristicLab.Data/3.3/DoubleArray.cs	(revision 17253)
@@ -21,7 +21,7 @@
 
 using System.Text;
+using HEAL.Attic;
 using HeuristicLab.Common;
 using HeuristicLab.Core;
-using HEAL.Attic;
 
 namespace HeuristicLab.Data {
@@ -36,5 +36,5 @@
     public DoubleArray() : base() { }
     public DoubleArray(int length) : base(length) { }
-    public DoubleArray(double[] elements) : base(elements) { }
+    public DoubleArray(double[] elements, bool @readonly = false) : base(elements, @readonly) { }
 
     public override IDeepCloneable Clone(Cloner cloner) {
@@ -67,4 +67,8 @@
       }
     }
+
+    public new DoubleArray AsReadOnly() {
+      return (DoubleArray)base.AsReadOnly();
+    }
   }
 }
Index: /branches/2521_ProblemRefactoring/HeuristicLab.Data/3.3/DoubleMatrix.cs
===================================================================
--- /branches/2521_ProblemRefactoring/HeuristicLab.Data/3.3/DoubleMatrix.cs	(revision 17252)
+++ /branches/2521_ProblemRefactoring/HeuristicLab.Data/3.3/DoubleMatrix.cs	(revision 17253)
@@ -73,4 +73,8 @@
     }
 
+    public new DoubleMatrix AsReadOnly() {
+      return (DoubleMatrix)base.AsReadOnly();
+    }
+
     #region IStringConvertibleMatrix Members
     int IStringConvertibleMatrix.Rows {
Index: /branches/2521_ProblemRefactoring/HeuristicLab.Data/3.3/DoubleValue.cs
===================================================================
--- /branches/2521_ProblemRefactoring/HeuristicLab.Data/3.3/DoubleValue.cs	(revision 17252)
+++ /branches/2521_ProblemRefactoring/HeuristicLab.Data/3.3/DoubleValue.cs	(revision 17253)
@@ -23,7 +23,7 @@
 using System.Drawing;
 using System.Text;
+using HEAL.Attic;
 using HeuristicLab.Common;
 using HeuristicLab.Core;
-using HEAL.Attic;
 
 namespace HeuristicLab.Data {
@@ -41,5 +41,5 @@
     }
     public DoubleValue() : base() { }
-    public DoubleValue(double value) : base(value) { }
+    public DoubleValue(double value, bool @readonly = false) : base(value, @readonly) { }
 
     public override IDeepCloneable Clone(Cloner cloner) {
@@ -85,4 +85,8 @@
     }
 
+    public new DoubleValue AsReadOnly() {
+      return (DoubleValue)base.AsReadOnly();
+    }
+
     #region IStringConvertibleValue Members
     bool IStringConvertibleValue.Validate(string value, out string errorMessage) {
Index: /branches/2521_ProblemRefactoring/HeuristicLab.Data/3.3/EnumValue.cs
===================================================================
--- /branches/2521_ProblemRefactoring/HeuristicLab.Data/3.3/EnumValue.cs	(revision 17252)
+++ /branches/2521_ProblemRefactoring/HeuristicLab.Data/3.3/EnumValue.cs	(revision 17253)
@@ -22,7 +22,7 @@
 using System;
 using System.Drawing;
+using HEAL.Attic;
 using HeuristicLab.Common;
 using HeuristicLab.Core;
-using HEAL.Attic;
 
 namespace HeuristicLab.Data {
@@ -39,12 +39,6 @@
     }
 
-    public EnumValue() {
-      this.value = default(T);
-      this.readOnly = false;
-    }
-    public EnumValue(T value) {
-      this.value = value;
-      this.readOnly = false;
-    }
+    public EnumValue() : base(default(T)) { }
+    public EnumValue(T value, bool @readonly = false) : base(value, @readonly) { }
 
     [StorableConstructor]
@@ -61,4 +55,8 @@
       return Value.CompareTo(other.Value);
     }
+
+    public new EnumValue<T> AsReadOnly() {
+      return (EnumValue<T>)base.AsReadOnly();
+    }
   }
 }
Index: /branches/2521_ProblemRefactoring/HeuristicLab.Data/3.3/IntArray.cs
===================================================================
--- /branches/2521_ProblemRefactoring/HeuristicLab.Data/3.3/IntArray.cs	(revision 17252)
+++ /branches/2521_ProblemRefactoring/HeuristicLab.Data/3.3/IntArray.cs	(revision 17253)
@@ -21,7 +21,7 @@
 
 using System.Text;
+using HEAL.Attic;
 using HeuristicLab.Common;
 using HeuristicLab.Core;
-using HEAL.Attic;
 
 namespace HeuristicLab.Data {
@@ -36,5 +36,5 @@
     public IntArray() : base() { }
     public IntArray(int length) : base(length) { }
-    public IntArray(int[] elements) : base(elements) { }
+    public IntArray(int[] elements, bool @readonly = false) : base(elements, @readonly) { }
 
     public override IDeepCloneable Clone(Cloner cloner) {
@@ -67,4 +67,8 @@
       }
     }
+
+    public new IntArray AsReadOnly() {
+      return (IntArray)base.AsReadOnly();
+    }
   }
 }
Index: /branches/2521_ProblemRefactoring/HeuristicLab.Data/3.3/IntMatrix.cs
===================================================================
--- /branches/2521_ProblemRefactoring/HeuristicLab.Data/3.3/IntMatrix.cs	(revision 17252)
+++ /branches/2521_ProblemRefactoring/HeuristicLab.Data/3.3/IntMatrix.cs	(revision 17253)
@@ -22,7 +22,7 @@
 using System.Collections.Generic;
 using System.Text;
+using HEAL.Attic;
 using HeuristicLab.Common;
 using HeuristicLab.Core;
-using HEAL.Attic;
 
 namespace HeuristicLab.Data {
@@ -39,7 +39,7 @@
     public IntMatrix(int rows, int columns, IEnumerable<string> columnNames) : base(rows, columns, columnNames) { }
     public IntMatrix(int rows, int columns, IEnumerable<string> columnNames,IEnumerable<string> rowNames) : base(rows, columns, columnNames,rowNames) { }
-    public IntMatrix(int[,] elements) : base(elements) { }
-    public IntMatrix(int[,] elements, IEnumerable<string> columnNames) : base(elements,columnNames) { }
-    public IntMatrix(int[,] elements, IEnumerable<string> columnNames, IEnumerable<string> rowNames) : base(elements,columnNames,rowNames) { }
+    public IntMatrix(int[,] elements, bool @readonly = false) : base(elements, @readonly) { }
+    public IntMatrix(int[,] elements, IEnumerable<string> columnNames, bool @readonly = false) : base(elements, columnNames, @readonly) { }
+    public IntMatrix(int[,] elements, IEnumerable<string> columnNames, IEnumerable<string> rowNames, bool @readonly = false) : base(elements, columnNames, rowNames, @readonly) { }
 
     public override IDeepCloneable Clone(Cloner cloner) {
@@ -73,4 +73,8 @@
     }
 
+    public new IntMatrix AsReadOnly() {
+      return (IntMatrix)base.AsReadOnly();
+    }
+
     #region IStringConvertibleMatrix Members
     int IStringConvertibleMatrix.Rows {
Index: /branches/2521_ProblemRefactoring/HeuristicLab.Data/3.3/IntValue.cs
===================================================================
--- /branches/2521_ProblemRefactoring/HeuristicLab.Data/3.3/IntValue.cs	(revision 17252)
+++ /branches/2521_ProblemRefactoring/HeuristicLab.Data/3.3/IntValue.cs	(revision 17253)
@@ -23,7 +23,7 @@
 using System.Drawing;
 using System.Text;
+using HEAL.Attic;
 using HeuristicLab.Common;
 using HeuristicLab.Core;
-using HEAL.Attic;
 
 namespace HeuristicLab.Data {
@@ -41,5 +41,5 @@
     }
     public IntValue() : base() { }
-    public IntValue(int value) : base(value) { }
+    public IntValue(int value, bool @readonly = false) : base(value, @readonly) { }
 
     public override IDeepCloneable Clone(Cloner cloner) {
@@ -81,4 +81,8 @@
     }
 
+    public new IntValue AsReadOnly() {
+      return (IntValue)base.AsReadOnly();
+    }
+
     #region IStringConvertibleValue Members
     bool IStringConvertibleValue.Validate(string value, out string errorMessage) {
Index: /branches/2521_ProblemRefactoring/HeuristicLab.Data/3.3/PercentArray.cs
===================================================================
--- /branches/2521_ProblemRefactoring/HeuristicLab.Data/3.3/PercentArray.cs	(revision 17252)
+++ /branches/2521_ProblemRefactoring/HeuristicLab.Data/3.3/PercentArray.cs	(revision 17253)
@@ -21,7 +21,7 @@
 
 using System.Text;
+using HEAL.Attic;
 using HeuristicLab.Common;
 using HeuristicLab.Core;
-using HEAL.Attic;
 
 namespace HeuristicLab.Data {
@@ -36,5 +36,5 @@
     public PercentArray() : base() { }
     public PercentArray(int length) : base(length) { }
-    public PercentArray(double[] elements) : base(elements) { }
+    public PercentArray(double[] elements, bool @readonly = false) : base(elements, @readonly) { }
 
     public override IDeepCloneable Clone(Cloner cloner) {
@@ -77,4 +77,8 @@
       }
     }
+
+    public new PercentArray AsReadOnly() {
+      return (PercentArray)base.AsReadOnly();
+    }
   }
 }
Index: /branches/2521_ProblemRefactoring/HeuristicLab.Data/3.3/PercentMatrix.cs
===================================================================
--- /branches/2521_ProblemRefactoring/HeuristicLab.Data/3.3/PercentMatrix.cs	(revision 17252)
+++ /branches/2521_ProblemRefactoring/HeuristicLab.Data/3.3/PercentMatrix.cs	(revision 17253)
@@ -22,7 +22,7 @@
 using System.Collections.Generic;
 using System.Text;
+using HEAL.Attic;
 using HeuristicLab.Common;
 using HeuristicLab.Core;
-using HEAL.Attic;
 
 namespace HeuristicLab.Data {
@@ -39,7 +39,7 @@
     public PercentMatrix(int rows, int columns, IEnumerable<string> columnNames) : base(rows, columns, columnNames) { }
     public PercentMatrix(int rows, int columns, IEnumerable<string> columnNames, IEnumerable<string> rowNames) : base(rows, columns, columnNames, rowNames) { }
-    public PercentMatrix(double[,] elements) : base(elements) { }
-    public PercentMatrix(double[,] elements, IEnumerable<string> columnNames) : base(elements, columnNames) { }
-    public PercentMatrix(double[,] elements, IEnumerable<string> columnNames, IEnumerable<string> rowNames) : base(elements, columnNames, rowNames) { }
+    public PercentMatrix(double[,] elements, bool @readonly = false) : base(elements, @readonly) { }
+    public PercentMatrix(double[,] elements, IEnumerable<string> columnNames, bool @readonly = false) : base(elements, columnNames, @readonly) { }
+    public PercentMatrix(double[,] elements, IEnumerable<string> columnNames, IEnumerable<string> rowNames, bool @readonly = false) : base(elements, columnNames, rowNames, @readonly) { }
 
     public override IDeepCloneable Clone(Cloner cloner) {
@@ -85,4 +85,8 @@
       }
     }
+
+    public new PercentMatrix AsReadOnly() {
+      return (PercentMatrix)base.AsReadOnly();
+    }
   }
 }
Index: /branches/2521_ProblemRefactoring/HeuristicLab.Data/3.3/PercentValue.cs
===================================================================
--- /branches/2521_ProblemRefactoring/HeuristicLab.Data/3.3/PercentValue.cs	(revision 17252)
+++ /branches/2521_ProblemRefactoring/HeuristicLab.Data/3.3/PercentValue.cs	(revision 17253)
@@ -21,7 +21,7 @@
 
 using System;
+using HEAL.Attic;
 using HeuristicLab.Common;
 using HeuristicLab.Core;
-using HEAL.Attic;
 
 namespace HeuristicLab.Data {
@@ -51,7 +51,7 @@
     }
     public PercentValue() : base() { }
-    public PercentValue(double value) : base(value) { }
-
-    public PercentValue(double value, bool restrictToUnitInterval)
+    public PercentValue(double value, bool @readonly = false) : base(value, @readonly) { }
+    // TODO: suggest to remove the following constructor [ABE]
+    public PercentValue(double value, bool restrictToUnitInterval, bool @readonly = false)
       : base() {
       this.restrictToUnitInterval = restrictToUnitInterval;
@@ -59,4 +59,5 @@
         throw new ArgumentException("Value must lie in the interval [0,1].");
       this.value = value;
+      this.readOnly = @readonly;
     }
 
@@ -101,4 +102,8 @@
       }
     }
+
+    public new PercentValue AsReadOnly() {
+      return (PercentValue)base.AsReadOnly();
+    }
   }
 }
Index: /branches/2521_ProblemRefactoring/HeuristicLab.Data/3.3/StringArray.cs
===================================================================
--- /branches/2521_ProblemRefactoring/HeuristicLab.Data/3.3/StringArray.cs	(revision 17252)
+++ /branches/2521_ProblemRefactoring/HeuristicLab.Data/3.3/StringArray.cs	(revision 17253)
@@ -26,7 +26,7 @@
 using System.Linq;
 using System.Text;
+using HEAL.Attic;
 using HeuristicLab.Common;
 using HeuristicLab.Core;
-using HEAL.Attic;
 
 namespace HeuristicLab.Data {
@@ -131,10 +131,10 @@
       elementNames = new List<string>();
     }
-    public StringArray(string[] elements) {
+    public StringArray(string[] elements, bool @readonly = false) {
       if (elements == null) throw new ArgumentNullException();
       array = new string[elements.Length];
       for (int i = 0; i < array.Length; i++)
         array[i] = elements[i] == null ? string.Empty : elements[i];
-      readOnly = false;
+      readOnly = @readonly;
       resizable = true;
       elementNames = new List<string>();
@@ -146,7 +146,8 @@
 
     public virtual StringArray AsReadOnly() {
-      StringArray readOnlyStringArray = (StringArray)this.Clone();
-      readOnlyStringArray.readOnly = true;
-      return readOnlyStringArray;
+      if (ReadOnly) return this;
+      var clone = (StringArray)this.Clone();
+      clone.readOnly = true;
+      return clone;
     }
     IValueTypeArray IValueTypeArray.AsReadOnly() {
Index: /branches/2521_ProblemRefactoring/HeuristicLab.Data/3.3/StringConvertibleArray.cs
===================================================================
--- /branches/2521_ProblemRefactoring/HeuristicLab.Data/3.3/StringConvertibleArray.cs	(revision 17252)
+++ /branches/2521_ProblemRefactoring/HeuristicLab.Data/3.3/StringConvertibleArray.cs	(revision 17253)
@@ -22,7 +22,7 @@
 #endregion
 
+using HEAL.Attic;
 using HeuristicLab.Common;
 using HeuristicLab.Core;
-using HEAL.Attic;
 
 namespace HeuristicLab.Data {
@@ -37,5 +37,5 @@
     protected StringConvertibleArray() : base() { }
     protected StringConvertibleArray(int length) : base(length) { }
-    protected StringConvertibleArray(T[] elements) : base(elements) { }
+    protected StringConvertibleArray(T[] elements, bool @readonly = false) : base(elements, @readonly) { }
 
     protected abstract bool Validate(string value, out string errorMessage);
Index: /branches/2521_ProblemRefactoring/HeuristicLab.Data/3.3/StringMatrix.cs
===================================================================
--- /branches/2521_ProblemRefactoring/HeuristicLab.Data/3.3/StringMatrix.cs	(revision 17252)
+++ /branches/2521_ProblemRefactoring/HeuristicLab.Data/3.3/StringMatrix.cs	(revision 17253)
@@ -26,7 +26,7 @@
 using System.Linq;
 using System.Text;
+using HEAL.Attic;
 using HeuristicLab.Common;
 using HeuristicLab.Core;
-using HEAL.Attic;
 
 namespace HeuristicLab.Data {
@@ -178,5 +178,5 @@
       RowNames = rowNames;
     }
-    public StringMatrix(string[,] elements) {
+    public StringMatrix(string[,] elements, bool @readonly = false) {
       if (elements == null) throw new ArgumentNullException();
       matrix = new string[elements.GetLength(0), elements.GetLength(1)];
@@ -188,12 +188,12 @@
       rowNames = new List<string>();
       sortableView = false;
-      readOnly = false;
-    }
-    protected StringMatrix(string[,] elements, IEnumerable<string> columnNames)
-      : this(elements) {
+      readOnly = @readonly;
+    }
+    protected StringMatrix(string[,] elements, IEnumerable<string> columnNames, bool @readonly = false)
+      : this(elements, @readonly) {
       ColumnNames = columnNames;
     }
-    protected StringMatrix(string[,] elements, IEnumerable<string> columnNames, IEnumerable<string> rowNames)
-      : this(elements, columnNames) {
+    protected StringMatrix(string[,] elements, IEnumerable<string> columnNames, IEnumerable<string> rowNames, bool @readonly = false)
+      : this(elements, columnNames, @readonly ) {
       RowNames = rowNames;
     }
@@ -204,7 +204,8 @@
 
     public virtual StringMatrix AsReadOnly() {
-      StringMatrix readOnlyStringMatrix = (StringMatrix)this.Clone();
-      readOnlyStringMatrix.readOnly = true;
-      return readOnlyStringMatrix;
+      if (ReadOnly) return this;
+      var clone = (StringMatrix)this.Clone();
+      clone.readOnly = true;
+      return clone;
     }
 
Index: /branches/2521_ProblemRefactoring/HeuristicLab.Data/3.3/StringValue.cs
===================================================================
--- /branches/2521_ProblemRefactoring/HeuristicLab.Data/3.3/StringValue.cs	(revision 17252)
+++ /branches/2521_ProblemRefactoring/HeuristicLab.Data/3.3/StringValue.cs	(revision 17253)
@@ -22,7 +22,7 @@
 using System;
 using System.Drawing;
+using HEAL.Attic;
 using HeuristicLab.Common;
 using HeuristicLab.Core;
-using HEAL.Attic;
 
 namespace HeuristicLab.Data {
@@ -66,7 +66,7 @@
       this.readOnly = false;
     }
-    public StringValue(string value) {
+    public StringValue(string value, bool @readonly = false) {
       this.value = value != null ? value : string.Empty;
-      this.readOnly = false;
+      this.readOnly = @readonly;
     }
 
@@ -76,7 +76,8 @@
 
     public virtual StringValue AsReadOnly() {
-      StringValue readOnlyStringValue = (StringValue)this.Clone();
-      readOnlyStringValue.readOnly = true;
-      return readOnlyStringValue;
+      if (ReadOnly) return this;
+      var clone = (StringValue)this.Clone();
+      clone.readOnly = true;
+      return clone;
     }
 
Index: /branches/2521_ProblemRefactoring/HeuristicLab.Data/3.3/TextValue.cs
===================================================================
--- /branches/2521_ProblemRefactoring/HeuristicLab.Data/3.3/TextValue.cs	(revision 17252)
+++ /branches/2521_ProblemRefactoring/HeuristicLab.Data/3.3/TextValue.cs	(revision 17253)
@@ -20,7 +20,7 @@
 #endregion
 
+using HEAL.Attic;
 using HeuristicLab.Common;
 using HeuristicLab.Core;
-using HEAL.Attic;
 
 namespace HeuristicLab.Data {
@@ -29,22 +29,11 @@
   public class TextValue : StringValue, ITextValue {
 
-    public TextValue() {
-      this.value = string.Empty;
-      this.readOnly = false;
-    }
-
-    public TextValue(string value) {
-      this.value = value ?? string.Empty;
-      this.readOnly = false;
-    }
+    public TextValue() : base() { }
+    public TextValue(string value, bool @readonly = false) : base(value ?? string.Empty, @readonly) { }
 
     [StorableConstructor]
     protected TextValue(StorableConstructorFlag _) : base(_) { }
 
-    protected TextValue(TextValue original, Cloner cloner)
-      : base(original, cloner) {
-      this.value = original.value ?? string.Empty;
-      this.readOnly = original.readOnly;
-    }
+    protected TextValue(TextValue original, Cloner cloner) : base(original, cloner) { }
 
     public override IDeepCloneable Clone(Cloner cloner) {
Index: /branches/2521_ProblemRefactoring/HeuristicLab.Data/3.3/TimeSpanValue.cs
===================================================================
--- /branches/2521_ProblemRefactoring/HeuristicLab.Data/3.3/TimeSpanValue.cs	(revision 17252)
+++ /branches/2521_ProblemRefactoring/HeuristicLab.Data/3.3/TimeSpanValue.cs	(revision 17253)
@@ -23,7 +23,7 @@
 using System.Globalization;
 using System.Text;
+using HEAL.Attic;
 using HeuristicLab.Common;
 using HeuristicLab.Core;
-using HEAL.Attic;
 
 namespace HeuristicLab.Data {
@@ -37,5 +37,5 @@
     }
     public TimeSpanValue() : base() { }
-    public TimeSpanValue(TimeSpan value) : base(value) { }
+    public TimeSpanValue(TimeSpan value, bool @readonly = false) : base(value, @readonly) { }
 
     public override IDeepCloneable Clone(Cloner cloner) {
@@ -80,4 +80,8 @@
     }
 
+    public new TimeSpanValue AsReadOnly() {
+      return (TimeSpanValue)base.AsReadOnly();
+    }
+
     #region IStringConvertibleValue Members
     bool IStringConvertibleValue.Validate(string value, out string errorMessage) {
Index: /branches/2521_ProblemRefactoring/HeuristicLab.Data/3.3/ValueTypeArray.cs
===================================================================
--- /branches/2521_ProblemRefactoring/HeuristicLab.Data/3.3/ValueTypeArray.cs	(revision 17252)
+++ /branches/2521_ProblemRefactoring/HeuristicLab.Data/3.3/ValueTypeArray.cs	(revision 17253)
@@ -26,7 +26,7 @@
 using System.Linq;
 using System.Text;
+using HEAL.Attic;
 using HeuristicLab.Common;
 using HeuristicLab.Core;
-using HEAL.Attic;
 
 namespace HeuristicLab.Data {
@@ -137,8 +137,8 @@
       elementNames = new List<string>();
     }
-    protected ValueTypeArray(T[] elements) {
+    protected ValueTypeArray(T[] elements, bool @readonly = false) {
       if (elements == null) throw new ArgumentNullException();
       array = (T[])elements.Clone();
-      readOnly = false;
+      readOnly = @readonly;
       resizable = true;
       elementNames = new List<string>();
@@ -146,7 +146,8 @@
 
     public virtual IValueTypeArray AsReadOnly() {
-      ValueTypeArray<T> readOnlyValueTypeArray = (ValueTypeArray<T>)this.Clone();
-      readOnlyValueTypeArray.readOnly = true;
-      return readOnlyValueTypeArray;
+      if (ReadOnly) return this;
+      var clone = (ValueTypeArray<T>)this.Clone();
+      clone.readOnly = true;
+      return clone;
     }
 
Index: /branches/2521_ProblemRefactoring/HeuristicLab.Data/3.3/ValueTypeMatrix.cs
===================================================================
--- /branches/2521_ProblemRefactoring/HeuristicLab.Data/3.3/ValueTypeMatrix.cs	(revision 17252)
+++ /branches/2521_ProblemRefactoring/HeuristicLab.Data/3.3/ValueTypeMatrix.cs	(revision 17253)
@@ -190,8 +190,8 @@
 
     public virtual ValueTypeMatrix<T> AsReadOnly() {
-      if (readOnly) return this;
-      var readOnlyValueTypeMatrix = (ValueTypeMatrix<T>)this.Clone();
-      readOnlyValueTypeMatrix.readOnly = true;
-      return readOnlyValueTypeMatrix;
+      if (ReadOnly) return this;
+      var clone = (ValueTypeMatrix<T>)this.Clone();
+      clone.readOnly = true;
+      return clone;
     }
 
Index: /branches/2521_ProblemRefactoring/HeuristicLab.Data/3.3/ValueTypeValue.cs
===================================================================
--- /branches/2521_ProblemRefactoring/HeuristicLab.Data/3.3/ValueTypeValue.cs	(revision 17252)
+++ /branches/2521_ProblemRefactoring/HeuristicLab.Data/3.3/ValueTypeValue.cs	(revision 17253)
@@ -22,7 +22,7 @@
 using System;
 using System.Drawing;
+using HEAL.Attic;
 using HeuristicLab.Common;
 using HeuristicLab.Core;
-using HEAL.Attic;
 
 namespace HeuristicLab.Data {
@@ -64,13 +64,14 @@
       this.readOnly = false;
     }
-    protected ValueTypeValue(T value) {
+    protected ValueTypeValue(T value, bool @readonly = false) {
       this.value = value;
-      this.readOnly = false;
+      this.readOnly = @readonly;
     }
 
     public virtual ValueTypeValue<T> AsReadOnly() {
-      ValueTypeValue<T> readOnlyValueTypeValue = (ValueTypeValue<T>)this.Clone();
-      readOnlyValueTypeValue.readOnly = true;
-      return readOnlyValueTypeValue;
+      if (ReadOnly) return this;
+      var clone = (ValueTypeValue<T>)this.Clone();
+      clone.readOnly = true;
+      return clone;
     }
 
Index: /branches/2521_ProblemRefactoring/HeuristicLab.Problems.Instances/3.3/Types/DistanceHelper.cs
===================================================================
--- /branches/2521_ProblemRefactoring/HeuristicLab.Problems.Instances/3.3/Types/DistanceHelper.cs	(revision 17252)
+++ /branches/2521_ProblemRefactoring/HeuristicLab.Problems.Instances/3.3/Types/DistanceHelper.cs	(revision 17253)
@@ -90,9 +90,9 @@
     }
 
-    private static double AttDistance(double x1, double y1, double x2, double y2) {
+    public static double AttDistance(double x1, double y1, double x2, double y2) {
       return Math.Ceiling(Math.Sqrt(((x1 - x2) * (x1 - x2) + (y1 - y2) * (y1 - y2)) / 10.0));
     }
 
-    private static double EuclideanDistance(double x1, double y1, double x2, double y2) {
+    public static double EuclideanDistance(double x1, double y1, double x2, double y2) {
       return Math.Sqrt((x1 - x2) * (x1 - x2) + (y1 - y2) * (y1 - y2));
     }
@@ -100,5 +100,5 @@
     private const double PI = 3.141592;
     private const double RADIUS = 6378.388;
-    private static double GeoDistance(double x1, double y1, double x2, double y2) {
+    public static double GeoDistance(double x1, double y1, double x2, double y2) {
       double latitude1, longitude1, latitude2, longitude2;
       double q1, q2, q3;
@@ -122,9 +122,9 @@
     }
 
-    private static double ManhattanDistance(double x1, double y1, double x2, double y2) {
+    public static double ManhattanDistance(double x1, double y1, double x2, double y2) {
       return Math.Round(Math.Abs(x1 - x2) + Math.Abs(y1 - y2), MidpointRounding.AwayFromZero);
     }
 
-    private static double MaximumDistance(double x1, double y1, double x2, double y2) {
+    public static double MaximumDistance(double x1, double y1, double x2, double y2) {
       return Math.Max(Math.Round(Math.Abs(x1 - x2), MidpointRounding.AwayFromZero), Math.Round(Math.Abs(y1 - y2), MidpointRounding.AwayFromZero));
     }
Index: /branches/2521_ProblemRefactoring/HeuristicLab.Problems.PTSP/3.3/AnalyticalPTSP.cs
===================================================================
--- /branches/2521_ProblemRefactoring/HeuristicLab.Problems.PTSP/3.3/AnalyticalPTSP.cs	(revision 17252)
+++ /branches/2521_ProblemRefactoring/HeuristicLab.Problems.PTSP/3.3/AnalyticalPTSP.cs	(revision 17253)
@@ -20,25 +20,20 @@
 #endregion
 
-using System;
 using System.Linq;
+using HEAL.Attic;
 using HeuristicLab.Common;
 using HeuristicLab.Core;
-using HeuristicLab.Data;
 using HeuristicLab.Encodings.PermutationEncoding;
-using HeuristicLab.Optimization;
-using HEAL.Attic;
 
 namespace HeuristicLab.Problems.PTSP {
-  [Item("Analytical Probabilistic Traveling Salesman Problem (PTSP)", "Represents a probabilistic traveling salesman problem where the expected tour length is calculated exactly.")]
+  [Item("Analytical Probabilistic TSP (p-TSP)", "Represents a probabilistic traveling salesman problem where the expected tour length is calculated exactly.")]
   [Creatable(CreatableAttribute.Categories.CombinatorialProblems)]
   [StorableType("509B6AB5-F4DE-4144-A031-43EEBAD02CA6")]
-  public sealed class AnalyticalProbabilisticTravelingSalesmanProblem : ProbabilisticTravelingSalesmanProblem {
+  public sealed class AnalyticalPTSP : ProbabilisticTSP {
 
     [StorableConstructor]
-    private AnalyticalProbabilisticTravelingSalesmanProblem(StorableConstructorFlag _) : base(_) { }
-    private AnalyticalProbabilisticTravelingSalesmanProblem(AnalyticalProbabilisticTravelingSalesmanProblem original, Cloner cloner) : base(original, cloner) { }
-    public AnalyticalProbabilisticTravelingSalesmanProblem() {
-      Operators.Add(new BestPTSPSolutionAnalyzer());
-
+    private AnalyticalPTSP(StorableConstructorFlag _) : base(_) { }
+    private AnalyticalPTSP(AnalyticalPTSP original, Cloner cloner) : base(original, cloner) { }
+    public AnalyticalPTSP() {
       Operators.Add(new PTSPAnalyticalInversionMoveEvaluator());
       Operators.Add(new PTSPAnalyticalInsertionMoveEvaluator());
@@ -53,8 +48,4 @@
       Operators.Add(new PTSPAnalyticalTwoPointFiveMoveEvaluator());
 
-      Operators.RemoveAll(x => x is SingleObjectiveMoveGenerator);
-      Operators.RemoveAll(x => x is SingleObjectiveMoveMaker);
-      Operators.RemoveAll(x => x is SingleObjectiveMoveEvaluator);
-
       Encoding.ConfigureOperators(Operators.OfType<IOperator>());
       foreach (var twopointfiveMoveOperator in Operators.OfType<ITwoPointFiveMoveOperator>()) {
@@ -64,21 +55,19 @@
 
     public override IDeepCloneable Clone(Cloner cloner) {
-      return new AnalyticalProbabilisticTravelingSalesmanProblem(this, cloner);
+      return new AnalyticalPTSP(this, cloner);
     }
 
     public override double Evaluate(Permutation tour, IRandom random) {
-      // abeham: Cache in local variable for performance reasons
-      var distanceMatrix = DistanceMatrix;
-      return Evaluate(tour, (a, b) => distanceMatrix[a, b], Probabilities);
+      return Evaluate(tour, ProbabilisticTSPData);
     }
 
-    public static double Evaluate(Permutation tour, Func<int, int, double> distance, DoubleArray probabilities) {
+    public static double Evaluate(Permutation tour, IProbabilisticTSPData data) {
       // Analytical evaluation
       var firstSum = 0.0;
       for (var i = 0; i < tour.Length - 1; i++) {
         for (var j = i + 1; j < tour.Length; j++) {
-          var prod1 = distance(tour[i], tour[j]) * probabilities[tour[i]] * probabilities[tour[j]];
+          var prod1 = data.GetDistance(tour[i], tour[j]) * data.GetProbability(tour[i]) * data.GetProbability(tour[j]);
           for (var k = i + 1; k < j; k++) {
-            prod1 = prod1 * (1 - probabilities[tour[k]]);
+            prod1 *= (1 - data.GetProbability(tour[k]));
           }
           firstSum += prod1;
@@ -88,10 +77,10 @@
       for (var j = 0; j < tour.Length; j++) {
         for (var i = 0; i < j; i++) {
-          var prod2 = distance(tour[j], tour[i]) * probabilities[tour[i]] * probabilities[tour[j]];
+          var prod2 = data.GetDistance(tour[j], tour[i]) * data.GetProbability(tour[i]) * data.GetProbability(tour[j]);
           for (var k = j + 1; k < tour.Length; k++) {
-            prod2 = prod2 * (1 - probabilities[tour[k]]);
+            prod2 *= (1 - data.GetProbability(tour[k]));
           }
           for (var k = 0; k < i; k++) {
-            prod2 = prod2 * (1 - probabilities[tour[k]]);
+            prod2 *= (1 - data.GetProbability(tour[k]));
           }
           secondSum += prod2;
@@ -100,8 +89,4 @@
       return firstSum + secondSum;
     }
-
-    public static double Evaluate(Permutation tour, DistanceMatrix distanceMatrix, DoubleArray probabilities) {
-      return Evaluate(tour, (a, b) => distanceMatrix[a, b], probabilities);
-    }
   }
 }
Index: anches/2521_ProblemRefactoring/HeuristicLab.Problems.PTSP/3.3/DistanceMatrix.cs
===================================================================
--- /branches/2521_ProblemRefactoring/HeuristicLab.Problems.PTSP/3.3/DistanceMatrix.cs	(revision 17252)
+++ 	(revision )
@@ -1,48 +1,0 @@
-﻿#region License Information
-/* HeuristicLab
- * Copyright (C) Heuristic and Evolutionary Algorithms Laboratory (HEAL)
- *
- * This file is part of HeuristicLab.
- *
- * HeuristicLab is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * HeuristicLab is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
- */
-#endregion
-
-using System.Collections.Generic;
-using HeuristicLab.Common;
-using HeuristicLab.Core;
-using HeuristicLab.Data;
-using HEAL.Attic;
-
-namespace HeuristicLab.Problems.PTSP {
-  [Item("DistanceMatrix", "Represents a distance matrix of a Probabilistic Traveling Salesman Problem.")]
-  [StorableType("C1E6E275-FA8C-448F-AB49-8779EB0738BE")]
-  public sealed class DistanceMatrix : DoubleMatrix {
-    [StorableConstructor]
-    private DistanceMatrix(StorableConstructorFlag _) : base(_) { }
-    public DistanceMatrix() : base() { }
-    public DistanceMatrix(int rows, int columns) : base(rows, columns) { }
-    public DistanceMatrix(int rows, int columns, IEnumerable<string> columnNames) : base(rows, columns, columnNames) { }
-    public DistanceMatrix(int rows, int columns, IEnumerable<string> columnNames, IEnumerable<string> rowNames) : base(rows, columns, columnNames, rowNames) { }
-    public DistanceMatrix(double[,] elements) : base(elements) { }
-    public DistanceMatrix(double[,] elements, IEnumerable<string> columnNames) : base(elements, columnNames) { }
-    public DistanceMatrix(double[,] elements, IEnumerable<string> columnNames, IEnumerable<string> rowNames) : base(elements, columnNames, rowNames) { }
-
-    public override IDeepCloneable Clone(Cloner cloner) {
-      // distance matrices are not cloned for performance reasons
-      cloner.RegisterClonedObject(this, this);
-      return this;
-    }
-  }
-}
Index: /branches/2521_ProblemRefactoring/HeuristicLab.Problems.PTSP/3.3/EstimatedPTSP.cs
===================================================================
--- /branches/2521_ProblemRefactoring/HeuristicLab.Problems.PTSP/3.3/EstimatedPTSP.cs	(revision 17252)
+++ /branches/2521_ProblemRefactoring/HeuristicLab.Problems.PTSP/3.3/EstimatedPTSP.cs	(revision 17253)
@@ -21,53 +21,57 @@
 
 using System;
+using System.Collections.Generic;
 using System.Linq;
+using HEAL.Attic;
 using HeuristicLab.Common;
 using HeuristicLab.Core;
 using HeuristicLab.Data;
 using HeuristicLab.Encodings.PermutationEncoding;
-using HeuristicLab.Optimization;
 using HeuristicLab.Parameters;
-using HEAL.Attic;
-using HeuristicLab.Problems.Instances;
 using HeuristicLab.Random;
 
 namespace HeuristicLab.Problems.PTSP {
-  [Item("Estimated Probabilistic Traveling Salesman Problem (PTSP)", "Represents a probabilistic traveling salesman problem where the expected tour length is estimated by averaging over the length of tours on a number of, so called, realizations.")]
+  [Item("Estimated Probabilistic TSP (p-TSP)", "Represents a probabilistic traveling salesman problem where the expected tour length is estimated by averaging over the length of tours on a number of, so called, realizations.")]
   [Creatable(CreatableAttribute.Categories.CombinatorialProblems)]
-  [StorableType("D1F1DE71-54E3-40B6-856F-685CD71D97F9")]
-  public sealed class EstimatedProbabilisticTravelingSalesmanProblem : ProbabilisticTravelingSalesmanProblem {
+  [StorableType("d1b4149b-8ab9-4314-8d96-9ea04a4d5b8b")]
+  public sealed class EstimatedPTSP : ProbabilisticTSP {
 
     #region Parameter Properties
-    public IValueParameter<ItemList<BoolArray>> RealizationsParameter {
-      get { return (IValueParameter<ItemList<BoolArray>>)Parameters["Realizations"]; }
-    }
-    public IFixedValueParameter<IntValue> RealizationsSizeParameter {
-      get { return (IFixedValueParameter<IntValue>)Parameters["RealizationsSize"]; }
-    }
+    [Storable] public IFixedValueParameter<IntValue> RealizationsSeedParameter { get; private set; }
+    [Storable] public IFixedValueParameter<IntValue> RealizationsParameter { get; private set; }
+    [Storable] private IValueParameter<ReadOnlyItemList<BoolArray>> RealizationDataParameter { get; set; }
     #endregion
 
     #region Properties
-    public ItemList<BoolArray> Realizations {
-      get { return RealizationsParameter.Value; }
-      set { RealizationsParameter.Value = value; }
-    }
-
-    public int RealizationsSize {
-      get { return RealizationsSizeParameter.Value.Value; }
-      set { RealizationsSizeParameter.Value.Value = value; }
+
+    public int RealizationsSeed {
+      get { return RealizationsSeedParameter.Value.Value; }
+      set { RealizationsSeedParameter.Value.Value = value; }
+    }
+
+    public int Realizations {
+      get { return RealizationsParameter.Value.Value; }
+      set { RealizationsParameter.Value.Value = value; }
+    }
+    
+    private ReadOnlyItemList<BoolArray> RealizationData {
+      get { return RealizationDataParameter.Value; }
+      set { RealizationDataParameter.Value = value; }
     }
     #endregion
 
     [StorableConstructor]
-    private EstimatedProbabilisticTravelingSalesmanProblem(StorableConstructorFlag _) : base(_) { }
-    private EstimatedProbabilisticTravelingSalesmanProblem(EstimatedProbabilisticTravelingSalesmanProblem original, Cloner cloner)
+    private EstimatedPTSP(StorableConstructorFlag _) : base(_) { }
+    private EstimatedPTSP(EstimatedPTSP original, Cloner cloner)
       : base(original, cloner) {
+      RealizationsSeedParameter = cloner.Clone(original.RealizationsSeedParameter);
+      RealizationsParameter = cloner.Clone(original.RealizationsParameter);
+      RealizationDataParameter = cloner.Clone(original.RealizationDataParameter);
       RegisterEventHandlers();
     }
-    public EstimatedProbabilisticTravelingSalesmanProblem() {
-      Parameters.Add(new FixedValueParameter<IntValue>("RealizationsSize", "Size of the sample for the estimation-based evaluation", new IntValue(100)));
-      Parameters.Add(new ValueParameter<ItemList<BoolArray>>("Realizations", "The list of samples drawn from all possible stochastic instances.", new ItemList<BoolArray>()));
-
-      Operators.Add(new BestPTSPSolutionAnalyzer());
+    public EstimatedPTSP() {
+      Parameters.Add(RealizationsSeedParameter = new FixedValueParameter<IntValue>("RealizationsSeed", "The starting seed of the RNG from which realizations should be drawn.", new IntValue(1)));
+      Parameters.Add(RealizationsParameter = new FixedValueParameter<IntValue>("Realizations", "The number of realizations that should be made.", new IntValue(100)));
+      Parameters.Add(RealizationDataParameter = new ValueParameter<ReadOnlyItemList<BoolArray>>("RealizationData", "The actual realizations.") { Hidden = true, GetsCollected = false });
 
       Operators.Add(new PTSPEstimatedInversionMoveEvaluator());
@@ -83,8 +87,4 @@
       Operators.Add(new PTSPEstimatedTwoPointFiveMoveEvaluator());
 
-      Operators.RemoveAll(x => x is SingleObjectiveMoveGenerator);
-      Operators.RemoveAll(x => x is SingleObjectiveMoveMaker);
-      Operators.RemoveAll(x => x is SingleObjectiveMoveEvaluator);
-
       Encoding.ConfigureOperators(Operators.OfType<IOperator>());
       foreach (var twopointfiveMoveOperator in Operators.OfType<ITwoPointFiveMoveOperator>()) {
@@ -97,5 +97,9 @@
 
     public override IDeepCloneable Clone(Cloner cloner) {
-      return new EstimatedProbabilisticTravelingSalesmanProblem(this, cloner);
+      return new EstimatedPTSP(this, cloner);
+    }
+
+    public override double Evaluate(Permutation tour, IRandom random) {
+      return Evaluate(tour, ProbabilisticTSPData, RealizationData);
     }
 
@@ -105,29 +109,14 @@
     }
 
-    private void RegisterEventHandlers() {
-      RealizationsSizeParameter.Value.ValueChanged += RealizationsSizeParameter_ValueChanged;
-    }
-
-    private void RealizationsSizeParameter_ValueChanged(object sender, EventArgs e) {
-      UpdateRealizations();
-    }
-
-    public override double Evaluate(Permutation tour, IRandom random) {
-      // abeham: Cache parameters in local variables for performance reasons
-      var realizations = Realizations;
-      var realizationsSize = RealizationsSize;
-      var useDistanceMatrix = UseDistanceMatrix;
-      var distanceMatrix = DistanceMatrix;
-      var distanceCalculator = DistanceCalculator;
-      var coordinates = Coordinates;
-
+    public static double Evaluate(Permutation tour, IProbabilisticTSPData data, IEnumerable<BoolArray> realizations) {
       // Estimation-based evaluation, here without calculating variance for faster evaluation
       var estimatedSum = 0.0;
-      for (var i = 0; i < realizations.Count; i++) {
+      var count = 0;
+      foreach (var r in realizations) {
         int singleRealization = -1, firstNode = -1;
-        for (var j = 0; j < realizations[i].Length; j++) {
-          if (realizations[i][tour[j]]) {
+        for (var j = 0; j < data.Cities; j++) {
+          if (r[tour[j]]) {
             if (singleRealization != -1) {
-              estimatedSum += useDistanceMatrix ? distanceMatrix[singleRealization, tour[j]] : distanceCalculator.Calculate(singleRealization, tour[j], coordinates);
+              estimatedSum += data.GetDistance(singleRealization, tour[j]);
             } else {
               firstNode = tour[j];
@@ -136,9 +125,9 @@
           }
         }
-        if (singleRealization != -1) {
-          estimatedSum += useDistanceMatrix ? distanceMatrix[singleRealization, firstNode] : distanceCalculator.Calculate(singleRealization, firstNode, coordinates);
-        }
-      }
-      return estimatedSum / realizationsSize;
+        if (singleRealization != -1)
+          estimatedSum += data.GetDistance(singleRealization, firstNode);
+        count++;
+      }
+      return estimatedSum / count;
     }
 
@@ -147,31 +136,21 @@
     /// </summary>
     /// <param name="tour">The tour between all cities.</param>
-    /// <param name="distanceMatrix">The distances between the cities.</param>
-    /// <param name="realizations">A sample of realizations of the stochastic instance</param>
+    /// <param name="data">The main parameters of the p-TSP.</param>
+    /// <param name="realizations">How many realizations to achieve.</param>
+    /// <param name="seed">The starting seed of generating the realizations.</param>
     /// <param name="variance">The estimated variance will be returned in addition to the mean.</param>
     /// <returns>A vector with length two containing mean and variance.</returns>
-    public static double Evaluate(Permutation tour, DistanceMatrix distanceMatrix, ItemList<BoolArray> realizations, out double variance) {
-      return Evaluate(tour, (a, b) => distanceMatrix[a, b], realizations, out variance);
-    }
-
-    /// <summary>
-    /// An evaluate method that can be used if mean as well as variance should be calculated
-    /// </summary>
-    /// <param name="tour">The tour between all cities.</param>
-    /// <param name="distance">A func that accepts the index of two cities and returns the distance as a double.</param>
-    /// <param name="realizations">A sample of realizations of the stochastic instance</param>
-    /// <param name="variance">The estimated variance will be returned in addition to the mean.</param>
-    /// <returns>A vector with length two containing mean and variance.</returns>
-    public static double Evaluate(Permutation tour, Func<int, int, double> distance, ItemList<BoolArray> realizations, out double variance) {
+    public static double Evaluate(Permutation tour, IProbabilisticTSPData data, IEnumerable<BoolArray> realizations, out double variance) {
       // Estimation-based evaluation
       var estimatedSum = 0.0;
-      var partialSums = new double[realizations.Count];
-      for (var i = 0; i < realizations.Count; i++) {
-        partialSums[i] = 0;
+      var partialSums = new List<double>();
+      var count = 0;
+      foreach (var r in realizations) {
+        var pSum = 0.0;
         int singleRealization = -1, firstNode = -1;
-        for (var j = 0; j < realizations[i].Length; j++) {
-          if (realizations[i][tour[j]]) {
+        for (var j = 0; j < data.Cities; j++) {
+          if (r[tour[j]]) {
             if (singleRealization != -1) {
-              partialSums[i] += distance(singleRealization, tour[j]);
+              pSum += data.GetDistance(singleRealization, tour[j]);
             } else {
               firstNode = tour[j];
@@ -181,43 +160,50 @@
         }
         if (singleRealization != -1) {
-          partialSums[i] += distance(singleRealization, firstNode);
-        }
-        estimatedSum += partialSums[i];
-      }
-      var mean = estimatedSum / realizations.Count;
+          pSum += data.GetDistance(singleRealization, firstNode);
+        }
+        estimatedSum += pSum;
+        partialSums.Add(pSum);
+        count++;
+      }
+      var mean = estimatedSum / count;
       variance = 0.0;
-      for (var i = 0; i < realizations.Count; i++) {
+      for (var i = 0; i < count; i++) {
         variance += Math.Pow((partialSums[i] - mean), 2);
       }
-      variance = variance / realizations.Count;
+      variance = variance / count;
       return mean;
     }
 
-    public override void Load(PTSPData data) {
-      base.Load(data);
+    private void RegisterEventHandlers() {
+      RealizationsParameter.Value.ValueChanged += RealizationsOnChanged;
+      RealizationsSeedParameter.Value.ValueChanged += RealizationsSeedOnChanged;
+    }
+
+    private void RealizationsSeedOnChanged(object sender, EventArgs e) {
       UpdateRealizations();
-
-      foreach (var op in Operators.OfType<IEstimatedPTSPOperator>()) {
-        op.RealizationsParameter.ActualName = RealizationsParameter.Name;
-      }
+    }
+
+    private void RealizationsOnChanged(object sender, EventArgs e) {
+      if (Realizations <= 0) Realizations = 1;
+      else UpdateRealizations();
     }
 
     private void UpdateRealizations() {
-      var realizations = new ItemList<BoolArray>(RealizationsSize);
-      var rand = new MersenneTwister();
-      for (var i = 0; i < RealizationsSize; i++) {
-        var newRealization = new BoolArray(Probabilities.Length);
-        var countOnes = 0;
-        do {
-          countOnes = 0;
-          for (var j = 0; j < Probabilities.Length; j++) {
-            newRealization[j] = Probabilities[j] < rand.NextDouble();
-            if (newRealization[j]) countOnes++;
+      var data = new List<BoolArray>(Realizations);
+      var rng = new FastRandom(RealizationsSeed);
+      for (var i = 0; i < Realizations; i++) {
+        var cities = 0;
+        var r = new bool[ProbabilisticTSPData.Cities];
+        for (var j = 0; j < ProbabilisticTSPData.Cities; j++) {
+          if (rng.NextDouble() < ProbabilisticTSPData.GetProbability(j)) {
+            r[j] = true;
+            cities++;
           }
-          // only generate realizations with at least 4 cities visited
-        } while (countOnes < 4 && Probabilities.Length > 3);
-        realizations.Add(newRealization);
-      }
-      Realizations = realizations;
+        }
+        if (cities > 0) {
+          data.Add(new BoolArray(r, @readonly: true));
+        }
+      }
+      RealizationData = (new ItemList<BoolArray>(data)).AsReadOnly();
     }
   }
Index: /branches/2521_ProblemRefactoring/HeuristicLab.Problems.PTSP/3.3/HeuristicLab.Problems.PTSP-3.3.csproj
===================================================================
--- /branches/2521_ProblemRefactoring/HeuristicLab.Problems.PTSP/3.3/HeuristicLab.Problems.PTSP-3.3.csproj	(revision 17252)
+++ /branches/2521_ProblemRefactoring/HeuristicLab.Problems.PTSP/3.3/HeuristicLab.Problems.PTSP-3.3.csproj	(revision 17253)
@@ -144,4 +144,9 @@
       <Private>False</Private>
     </ProjectReference>
+    <ProjectReference Include="..\..\HeuristicLab.Problems.TravelingSalesman\3.3\HeuristicLab.Problems.TravelingSalesman-3.3.csproj">
+      <Project>{d767c38d-8014-46b0-9a32-03a3aecce34a}</Project>
+      <Name>HeuristicLab.Problems.TravelingSalesman-3.3</Name>
+      <Private>False</Private>
+    </ProjectReference>
     <ProjectReference Include="..\..\HeuristicLab.Random\3.3\HeuristicLab.Random-3.3.csproj">
       <Project>{F4539FB6-4708-40C9-BE64-0A1390AEA197}</Project>
@@ -160,17 +165,8 @@
   </ItemGroup>
   <ItemGroup>
+    <Compile Include="PTSPData.cs" />
     <None Include="Properties\AssemblyInfo.cs.frame" />
     <None Include="Plugin.cs.frame" />
     <Compile Include="AnalyticalPTSP.cs" />
-    <Compile Include="Analyzers\BestPTSPSolutionAnalyzer.cs" />
-    <Compile Include="DistanceCalculators\MaximumDistance.cs" />
-    <Compile Include="DistanceCalculators\ManhattanDistance.cs" />
-    <Compile Include="DistanceCalculators\GeoDistance.cs" />
-    <Compile Include="DistanceCalculators\DistanceCalculator.cs" />
-    <Compile Include="DistanceCalculators\AttDistance.cs" />
-    <Compile Include="DistanceCalculators\UpperEuclideanDistance.cs" />
-    <Compile Include="DistanceCalculators\RoundedEuclideanDistance.cs" />
-    <Compile Include="DistanceCalculators\EuclideanDistance.cs" />
-    <Compile Include="DistanceMatrix.cs" />
     <Compile Include="EstimatedPTSP.cs" />
     <Compile Include="Improvers\PTSPAnalyticalInsertionLocalImprovement.cs" />
@@ -199,5 +195,4 @@
     <Compile Include="Moves\TwoPointFiveOpt\TwoPointFiveMoveMaker.cs" />
     <Compile Include="Moves\TwoPointFiveOpt\TwoPointFiveMove.cs" />
-    <Compile Include="PathPTSPTour.cs" />
     <Compile Include="PTSP.cs" />
     <Compile Include="Plugin.cs" />
Index: /branches/2521_ProblemRefactoring/HeuristicLab.Problems.PTSP/3.3/Improvers/PTSPAnalyticalInsertionLocalImprovement.cs
===================================================================
--- /branches/2521_ProblemRefactoring/HeuristicLab.Problems.PTSP/3.3/Improvers/PTSPAnalyticalInsertionLocalImprovement.cs	(revision 17252)
+++ /branches/2521_ProblemRefactoring/HeuristicLab.Problems.PTSP/3.3/Improvers/PTSPAnalyticalInsertionLocalImprovement.cs	(revision 17253)
@@ -22,4 +22,5 @@
 using System;
 using System.Threading;
+using HEAL.Attic;
 using HeuristicLab.Common;
 using HeuristicLab.Core;
@@ -29,5 +30,4 @@
 using HeuristicLab.Optimization;
 using HeuristicLab.Parameters;
-using HEAL.Attic;
 
 namespace HeuristicLab.Problems.PTSP {
@@ -39,5 +39,5 @@
   /// </remarks>
   [Item("PTSP Analytical Insertion Local Improvement", "An operator that improves probabilistic traveling salesman solutions. The operator tries to improve the probabilistic traveling salesman solution by swapping two randomly chosen edges for a certain number of times.")]
-  [StorableType("D63C6CB3-A5EF-4270-A252-2F5EBF1ED163")]
+  [StorableType("5adca9d8-02b2-4937-9f79-a24d8ea8ea19")]
   public sealed class PTSPAnalyticalInsertionLocalImprovement : SingleSuccessorOperator, IAnalyticalPTSPOperator, ILocalImprovementOperator {
 
@@ -70,10 +70,6 @@
     }
 
-    public ILookupParameter<DistanceMatrix> DistanceMatrixParameter {
-      get { return (ILookupParameter<DistanceMatrix>)Parameters["DistanceMatrix"]; }
-    }
-
-    public ILookupParameter<DoubleArray> ProbabilitiesParameter {
-      get { return (ILookupParameter<DoubleArray>)Parameters["Probabilities"]; }
+    public ILookupParameter<IProbabilisticTSPData> ProbabilisticTSPDataParameter {
+      get { return (ILookupParameter<IProbabilisticTSPData>)Parameters["PTSP Data"]; }
     }
 
@@ -90,6 +86,5 @@
       Parameters.Add(new LookupParameter<DoubleValue>("Quality", "The quality value of the assignment."));
       Parameters.Add(new LookupParameter<BoolValue>("Maximization", "True if the problem should be maximized or minimized."));
-      Parameters.Add(new LookupParameter<DistanceMatrix>("DistanceMatrix", "The matrix which contains the distances between the cities."));
-      Parameters.Add(new LookupParameter<DoubleArray>("Probabilities", "The list of probabilities of the cities to appear."));
+      Parameters.Add(new LookupParameter<IProbabilisticTSPData>("PTSP Data", "The main parameters of the p-TSP."));
     }
 
@@ -98,7 +93,5 @@
     }
 
-    public static void Improve(Permutation assignment, DoubleMatrix distances, DoubleValue quality, IntValue localIterations, IntValue evaluatedSolutions, bool maximization, int maxIterations, DoubleArray probabilities, CancellationToken cancellation) {
-      var distanceM = (DistanceMatrix)distances;
-      Func<int, int, double> distance = (a, b) => distanceM[a, b];
+    public static void Improve(Permutation assignment, IProbabilisticTSPData data, DoubleValue quality, IntValue localIterations, IntValue evaluatedSolutions, bool maximization, int maxIterations, CancellationToken cancellation) {
       for (var i = localIterations.Value; i < maxIterations; i++) {
         TranslocationMove bestMove = null;
@@ -106,5 +99,5 @@
         var evaluations = 0.0;
         foreach (var move in ExhaustiveInsertionMoveGenerator.Generate(assignment)) {
-          var moveQuality = PTSPAnalyticalInsertionMoveEvaluator.EvaluateMove(assignment, move, distance, probabilities);
+          var moveQuality = PTSPAnalyticalInsertionMoveEvaluator.EvaluateMove(assignment, move, data);
           evaluations++;
           if (maximization && moveQuality > bestQuality
@@ -127,9 +120,8 @@
       var assignment = PermutationParameter.ActualValue;
       var maximization = MaximizationParameter.ActualValue.Value;
-      var distances = DistanceMatrixParameter.ActualValue;
       var quality = QualityParameter.ActualValue;
       var localIterations = LocalIterationsParameter.ActualValue;
       var evaluations = EvaluatedSolutionsParameter.ActualValue;
-      var probabilities = ProbabilitiesParameter.ActualValue;
+      var data = ProbabilisticTSPDataParameter.ActualValue;
       if (localIterations == null) {
         localIterations = new IntValue(0);
@@ -137,5 +129,5 @@
       }
 
-      Improve(assignment, distances, quality, localIterations, evaluations, maximization, maxIterations, probabilities, CancellationToken);
+      Improve(assignment, data, quality, localIterations, evaluations, maximization, maxIterations, CancellationToken);
 
       localIterations.Value = 0;
Index: /branches/2521_ProblemRefactoring/HeuristicLab.Problems.PTSP/3.3/Improvers/PTSPAnalyticalInversionLocalImprovement.cs
===================================================================
--- /branches/2521_ProblemRefactoring/HeuristicLab.Problems.PTSP/3.3/Improvers/PTSPAnalyticalInversionLocalImprovement.cs	(revision 17252)
+++ /branches/2521_ProblemRefactoring/HeuristicLab.Problems.PTSP/3.3/Improvers/PTSPAnalyticalInversionLocalImprovement.cs	(revision 17253)
@@ -22,4 +22,5 @@
 using System;
 using System.Threading;
+using HEAL.Attic;
 using HeuristicLab.Common;
 using HeuristicLab.Core;
@@ -29,5 +30,4 @@
 using HeuristicLab.Optimization;
 using HeuristicLab.Parameters;
-using HEAL.Attic;
 
 namespace HeuristicLab.Problems.PTSP {
@@ -39,5 +39,5 @@
   /// </remarks>
   [Item("PTSP Analytical Inversion Local Improvement", "An operator that improves probabilistic traveling salesman solutions. The operator tries to improve the probabilistic traveling salesman solution by swapping two randomly chosen edges for a certain number of times.")]
-  [StorableType("1594EB4E-A874-485A-B1D5-E622F9FF3FD8")]
+  [StorableType("88147d6a-e843-4f65-8058-421453b5206a")]
   public sealed class PTSPAnalyticalInversionLocalImprovement : SingleSuccessorOperator, IAnalyticalPTSPOperator, ILocalImprovementOperator {
 
@@ -70,10 +70,6 @@
     }
 
-    public ILookupParameter<DistanceMatrix> DistanceMatrixParameter {
-      get { return (ILookupParameter<DistanceMatrix>)Parameters["DistanceMatrix"]; }
-    }
-
-    public ILookupParameter<DoubleArray> ProbabilitiesParameter {
-      get { return (ILookupParameter<DoubleArray>)Parameters["Probabilities"]; }
+    public ILookupParameter<IProbabilisticTSPData> ProbabilisticTSPDataParameter {
+      get { return (ILookupParameter<IProbabilisticTSPData>)Parameters["PTSP Data"]; }
     }
 
@@ -90,6 +86,5 @@
       Parameters.Add(new LookupParameter<DoubleValue>("Quality", "The quality value of the assignment."));
       Parameters.Add(new LookupParameter<BoolValue>("Maximization", "True if the problem should be maximized or minimized."));
-      Parameters.Add(new LookupParameter<DistanceMatrix>("DistanceMatrix", "The matrix which contains the distances between the cities."));
-      Parameters.Add(new LookupParameter<DoubleArray>("Probabilities", "The list of probabilities of the cities to appear."));
+      Parameters.Add(new LookupParameter<IProbabilisticTSPData>("PTSP Data", "The main parameters of the p-TSP."));
     }
 
@@ -98,7 +93,5 @@
     }
 
-    public static void Improve(Permutation assignment, DoubleMatrix distances, DoubleValue quality, IntValue localIterations, IntValue evaluatedSolutions, bool maximization, int maxIterations, DoubleArray probabilities, CancellationToken cancellation) {
-      var distanceM = (DistanceMatrix)distances;
-      Func<int, int, double> distance = (a, b) => distanceM[a, b];
+    public static void Improve(Permutation assignment, IProbabilisticTSPData data, DoubleValue quality, IntValue localIterations, IntValue evaluatedSolutions, bool maximization, int maxIterations, CancellationToken cancellation) {
       for (var i = localIterations.Value; i < maxIterations; i++) {
         InversionMove bestMove = null;
@@ -106,5 +99,5 @@
         var evaluations = 0.0;
         foreach (var move in ExhaustiveInversionMoveGenerator.Generate(assignment)) {
-          var moveQuality = PTSPAnalyticalInversionMoveEvaluator.EvaluateMove(assignment, move, distance, probabilities);
+          var moveQuality = PTSPAnalyticalInversionMoveEvaluator.EvaluateMove(assignment, move, data);
           evaluations++;
           if (maximization && moveQuality > bestQuality
@@ -127,9 +120,8 @@
       var assignment = PermutationParameter.ActualValue;
       var maximization = MaximizationParameter.ActualValue.Value;
-      var distances = DistanceMatrixParameter.ActualValue;
       var quality = QualityParameter.ActualValue;
       var localIterations = LocalIterationsParameter.ActualValue;
       var evaluations = EvaluatedSolutionsParameter.ActualValue;
-      var probabilities = ProbabilitiesParameter.ActualValue;
+      var data = ProbabilisticTSPDataParameter.ActualValue;
       if (localIterations == null) {
         localIterations = new IntValue(0);
@@ -137,5 +129,5 @@
       }
 
-      Improve(assignment, distances, quality, localIterations, evaluations, maximization, maxIterations, probabilities, CancellationToken);
+      Improve(assignment, data, quality, localIterations, evaluations, maximization, maxIterations, CancellationToken);
 
       localIterations.Value = 0;
Index: /branches/2521_ProblemRefactoring/HeuristicLab.Problems.PTSP/3.3/Improvers/PTSPAnalyticalTwoPointFiveLocalImprovement.cs
===================================================================
--- /branches/2521_ProblemRefactoring/HeuristicLab.Problems.PTSP/3.3/Improvers/PTSPAnalyticalTwoPointFiveLocalImprovement.cs	(revision 17252)
+++ /branches/2521_ProblemRefactoring/HeuristicLab.Problems.PTSP/3.3/Improvers/PTSPAnalyticalTwoPointFiveLocalImprovement.cs	(revision 17253)
@@ -22,4 +22,5 @@
 using System;
 using System.Threading;
+using HEAL.Attic;
 using HeuristicLab.Common;
 using HeuristicLab.Core;
@@ -29,5 +30,4 @@
 using HeuristicLab.Optimization;
 using HeuristicLab.Parameters;
-using HEAL.Attic;
 
 namespace HeuristicLab.Problems.PTSP {
@@ -39,5 +39,5 @@
   /// </remarks>
   [Item("PTSP Analytical 2.5 Local Improvement", "An operator that improves probabilistic traveling salesman solutions. The operator tries to improve the probabilistic traveling salesman solution by swapping two randomly chosen edges for a certain number of times.")]
-  [StorableType("C139639F-D6DD-4756-8482-24F12A78C8E9")]
+  [StorableType("6e07195e-0da7-45ea-9385-0c66594127db")]
   public sealed class PTSPAnalyticalTwoPointFiveLocalImprovement : SingleSuccessorOperator, IAnalyticalPTSPOperator, ILocalImprovementOperator {
 
@@ -70,10 +70,6 @@
     }
 
-    public ILookupParameter<DistanceMatrix> DistanceMatrixParameter {
-      get { return (ILookupParameter<DistanceMatrix>)Parameters["DistanceMatrix"]; }
-    }
-
-    public ILookupParameter<DoubleArray> ProbabilitiesParameter {
-      get { return (ILookupParameter<DoubleArray>)Parameters["Probabilities"]; }
+    public ILookupParameter<IProbabilisticTSPData> ProbabilisticTSPDataParameter {
+      get { return (ILookupParameter<IProbabilisticTSPData>)Parameters["PTSP Data"]; }
     }
 
@@ -90,6 +86,5 @@
       Parameters.Add(new LookupParameter<DoubleValue>("Quality", "The quality value of the assignment."));
       Parameters.Add(new LookupParameter<BoolValue>("Maximization", "True if the problem should be maximized or minimized."));
-      Parameters.Add(new LookupParameter<DistanceMatrix>("DistanceMatrix", "The matrix which contains the distances between the cities."));
-      Parameters.Add(new LookupParameter<DoubleArray>("Probabilities", "The list of probabilities of the cities to appear."));
+      Parameters.Add(new LookupParameter<IProbabilisticTSPData>("PTSP Data", "The main parameters of the p-TSP."));
     }
 
@@ -98,7 +93,5 @@
     }
 
-    public static void Improve(Permutation assignment, DoubleMatrix distances, DoubleValue quality, IntValue localIterations, IntValue evaluatedSolutions, bool maximization, int maxIterations, DoubleArray probabilities, CancellationToken cancellation) {
-      var distanceM = (DistanceMatrix)distances;
-      Func<int, int, double> distance = (a, b) => distanceM[a, b];
+    public static void Improve(Permutation assignment, IProbabilisticTSPData data, DoubleValue quality, IntValue localIterations, IntValue evaluatedSolutions, bool maximization, int maxIterations, CancellationToken cancellation) {
       for (var i = localIterations.Value; i < maxIterations; i++) {
         TwoPointFiveMove bestMove = null;
@@ -106,5 +99,5 @@
         var evaluations = 0.0;
         foreach (var move in ExhaustiveTwoPointFiveMoveGenerator.Generate(assignment)) {
-          var moveQuality = PTSPAnalyticalTwoPointFiveMoveEvaluator.EvaluateMove(assignment, move, distance, probabilities);
+          var moveQuality = PTSPAnalyticalTwoPointFiveMoveEvaluator.EvaluateMove(assignment, move, data);
           evaluations++;
           if (maximization && moveQuality > bestQuality
@@ -127,9 +120,8 @@
       var assignment = PermutationParameter.ActualValue;
       var maximization = MaximizationParameter.ActualValue.Value;
-      var distances = DistanceMatrixParameter.ActualValue;
       var quality = QualityParameter.ActualValue;
       var localIterations = LocalIterationsParameter.ActualValue;
       var evaluations = EvaluatedSolutionsParameter.ActualValue;
-      var probabilities = ProbabilitiesParameter.ActualValue;
+      var data = ProbabilisticTSPDataParameter.ActualValue;
       if (localIterations == null) {
         localIterations = new IntValue(0);
@@ -137,5 +129,5 @@
       }
 
-      Improve(assignment, distances, quality, localIterations, evaluations, maximization, maxIterations, probabilities, CancellationToken);
+      Improve(assignment, data, quality, localIterations, evaluations, maximization, maxIterations, CancellationToken);
 
       localIterations.Value = 0;
Index: /branches/2521_ProblemRefactoring/HeuristicLab.Problems.PTSP/3.3/Improvers/PTSPEstimatedInsertionLocalImprovement.cs
===================================================================
--- /branches/2521_ProblemRefactoring/HeuristicLab.Problems.PTSP/3.3/Improvers/PTSPEstimatedInsertionLocalImprovement.cs	(revision 17252)
+++ /branches/2521_ProblemRefactoring/HeuristicLab.Problems.PTSP/3.3/Improvers/PTSPEstimatedInsertionLocalImprovement.cs	(revision 17253)
@@ -21,5 +21,8 @@
 
 using System;
+using System.Collections.Generic;
+using System.Linq;
 using System.Threading;
+using HEAL.Attic;
 using HeuristicLab.Common;
 using HeuristicLab.Core;
@@ -29,5 +32,4 @@
 using HeuristicLab.Optimization;
 using HeuristicLab.Parameters;
-using HEAL.Attic;
 
 namespace HeuristicLab.Problems.PTSP {
@@ -70,10 +72,10 @@
     }
 
-    public ILookupParameter<DistanceMatrix> DistanceMatrixParameter {
-      get { return (ILookupParameter<DistanceMatrix>)Parameters["DistanceMatrix"]; }
+    public ILookupParameter<IProbabilisticTSPData> ProbabilisticTSPDataParameter {
+      get { return (ILookupParameter<IProbabilisticTSPData>)Parameters["PTSP Data"]; }
     }
 
-    public ILookupParameter<ItemList<BoolArray>> RealizationsParameter {
-      get { return (ILookupParameter<ItemList<BoolArray>>)Parameters["Realizations"]; }
+    public ILookupParameter<ReadOnlyItemList<BoolArray>> RealizationsParameter {
+      get { return (ILookupParameter<ReadOnlyItemList<BoolArray>>)Parameters["Realizations"]; }
     }
 
@@ -90,5 +92,5 @@
       Parameters.Add(new LookupParameter<DoubleValue>("Quality", "The quality value of the assignment."));
       Parameters.Add(new LookupParameter<BoolValue>("Maximization", "True if the problem should be maximized or minimized."));
-      Parameters.Add(new LookupParameter<DistanceMatrix>("DistanceMatrix", "The matrix which contains the distances between the cities."));
+      Parameters.Add(new LookupParameter<IProbabilisticTSPData>("PTSP Data", "The main parameters of the p-TSP."));
       Parameters.Add(new LookupParameter<ItemList<BoolArray>>("Realizations", "The list of samples drawn from all possible stochastic instances."));
     }
@@ -98,7 +100,5 @@
     }
 
-    public static void Improve(Permutation assignment, DoubleMatrix distances, DoubleValue quality, IntValue localIterations, IntValue evaluatedSolutions, bool maximization, int maxIterations, ItemList<BoolArray> realizations, CancellationToken cancellation) {
-      var distanceM = (DistanceMatrix)distances;
-      Func<int, int, double> distance = (a, b) => distanceM[a, b];
+    public static void Improve(Permutation assignment, IProbabilisticTSPData data, DoubleValue quality, IntValue localIterations, IntValue evaluatedSolutions, bool maximization, int maxIterations, IEnumerable<BoolArray> realizations, CancellationToken cancellation) {
       for (var i = localIterations.Value; i < maxIterations; i++) {
         TranslocationMove bestMove = null;
@@ -106,6 +106,6 @@
         double evaluations = 0.0;
         foreach (var move in ExhaustiveInsertionMoveGenerator.Generate(assignment)) {
-          double moveQuality = PTSPEstimatedInsertionMoveEvaluator.EvaluateMove(assignment, move, distance, realizations);
-          evaluations += realizations.Count * 6.0 / (assignment.Length * assignment.Length);
+          double moveQuality = PTSPEstimatedInsertionMoveEvaluator.EvaluateMove(assignment, move, data, realizations);
+          evaluations += realizations.Count() * 6.0 / (assignment.Length * assignment.Length);
           if (maximization && moveQuality > bestQuality
             || !maximization && moveQuality < bestQuality) {
@@ -127,8 +127,8 @@
       var assignment = PermutationParameter.ActualValue;
       var maximization = MaximizationParameter.ActualValue.Value;
-      var distances = DistanceMatrixParameter.ActualValue;
       var quality = QualityParameter.ActualValue;
       var localIterations = LocalIterationsParameter.ActualValue;
       var evaluations = EvaluatedSolutionsParameter.ActualValue;
+      var data = ProbabilisticTSPDataParameter.ActualValue;
       var realizations = RealizationsParameter.ActualValue;
       if (localIterations == null) {
@@ -137,5 +137,5 @@
       }
 
-      Improve(assignment, distances, quality, localIterations, evaluations, maximization, maxIterations, realizations, CancellationToken);
+      Improve(assignment, data, quality, localIterations, evaluations, maximization, maxIterations, realizations, CancellationToken);
 
       localIterations.Value = 0;
Index: /branches/2521_ProblemRefactoring/HeuristicLab.Problems.PTSP/3.3/Improvers/PTSPEstimatedInversionLocalImprovement.cs
===================================================================
--- /branches/2521_ProblemRefactoring/HeuristicLab.Problems.PTSP/3.3/Improvers/PTSPEstimatedInversionLocalImprovement.cs	(revision 17252)
+++ /branches/2521_ProblemRefactoring/HeuristicLab.Problems.PTSP/3.3/Improvers/PTSPEstimatedInversionLocalImprovement.cs	(revision 17253)
@@ -21,5 +21,8 @@
 
 using System;
+using System.Collections.Generic;
+using System.Linq;
 using System.Threading;
+using HEAL.Attic;
 using HeuristicLab.Common;
 using HeuristicLab.Core;
@@ -29,5 +32,4 @@
 using HeuristicLab.Optimization;
 using HeuristicLab.Parameters;
-using HEAL.Attic;
 
 namespace HeuristicLab.Problems.PTSP {
@@ -70,10 +72,10 @@
     }
 
-    public ILookupParameter<DistanceMatrix> DistanceMatrixParameter {
-      get { return (ILookupParameter<DistanceMatrix>)Parameters["DistanceMatrix"]; }
+    public ILookupParameter<IProbabilisticTSPData> ProbabilisticTSPDataParameter {
+      get { return (ILookupParameter<IProbabilisticTSPData>)Parameters["PTSP Data"]; }
     }
 
-    public ILookupParameter<ItemList<BoolArray>> RealizationsParameter {
-      get { return (ILookupParameter<ItemList<BoolArray>>)Parameters["Realizations"]; }
+    public ILookupParameter<ReadOnlyItemList<BoolArray>> RealizationsParameter {
+      get { return (ILookupParameter<ReadOnlyItemList<BoolArray>>)Parameters["Realizations"]; }
     }
 
@@ -90,5 +92,5 @@
       Parameters.Add(new LookupParameter<DoubleValue>("Quality", "The quality value of the assignment."));
       Parameters.Add(new LookupParameter<BoolValue>("Maximization", "True if the problem should be maximized or minimized."));
-      Parameters.Add(new LookupParameter<DistanceMatrix>("DistanceMatrix", "The matrix which contains the distances between the cities."));
+      Parameters.Add(new LookupParameter<IProbabilisticTSPData>("PTSP Data", "The main parameters of the p-TSP."));
       Parameters.Add(new LookupParameter<ItemList<BoolArray>>("Realizations", "The list of samples drawn from all possible stochastic instances."));
     }
@@ -98,7 +100,5 @@
     }
 
-    public static void Improve(Permutation assignment, DoubleMatrix distances, DoubleValue quality, IntValue localIterations, IntValue evaluatedSolutions, bool maximization, int maxIterations, ItemList<BoolArray> realizations, CancellationToken cancellation) {
-      var distanceM = (DistanceMatrix)distances;
-      Func<int, int, double> distance = (a, b) => distanceM[a, b];
+    public static void Improve(Permutation assignment, IProbabilisticTSPData data, DoubleValue quality, IntValue localIterations, IntValue evaluatedSolutions, bool maximization, int maxIterations, IEnumerable<BoolArray> realizations, CancellationToken cancellation) {
       for (var i = localIterations.Value; i < maxIterations; i++) {
         InversionMove bestMove = null;
@@ -106,6 +106,6 @@
         double evaluations = 0.0;
         foreach (var move in ExhaustiveInversionMoveGenerator.Generate(assignment)) {
-          double moveQuality = PTSPEstimatedInversionMoveEvaluator.EvaluateMove(assignment, move, distance, realizations);
-          evaluations += realizations.Count * 4.0 / (assignment.Length * assignment.Length);
+          double moveQuality = PTSPEstimatedInversionMoveEvaluator.EvaluateMove(assignment, move, data, realizations);
+          evaluations += realizations.Count() * 4.0 / (assignment.Length * assignment.Length);
           if (maximization && moveQuality > bestQuality
             || !maximization && moveQuality < bestQuality) {
@@ -127,8 +127,8 @@
       var assignment = PermutationParameter.ActualValue;
       var maximization = MaximizationParameter.ActualValue.Value;
-      var distances = DistanceMatrixParameter.ActualValue;
       var quality = QualityParameter.ActualValue;
       var localIterations = LocalIterationsParameter.ActualValue;
       var evaluations = EvaluatedSolutionsParameter.ActualValue;
+      var data = ProbabilisticTSPDataParameter.ActualValue;
       var realizations = RealizationsParameter.ActualValue;
       if (localIterations == null) {
@@ -137,5 +137,5 @@
       }
 
-      Improve(assignment, distances, quality, localIterations, evaluations, maximization, maxIterations, realizations, CancellationToken);
+      Improve(assignment, data, quality, localIterations, evaluations, maximization, maxIterations, realizations, CancellationToken);
 
       localIterations.Value = 0;
Index: /branches/2521_ProblemRefactoring/HeuristicLab.Problems.PTSP/3.3/Improvers/PTSPEstimatedTwoPointFiveLocalImprovement.cs
===================================================================
--- /branches/2521_ProblemRefactoring/HeuristicLab.Problems.PTSP/3.3/Improvers/PTSPEstimatedTwoPointFiveLocalImprovement.cs	(revision 17252)
+++ /branches/2521_ProblemRefactoring/HeuristicLab.Problems.PTSP/3.3/Improvers/PTSPEstimatedTwoPointFiveLocalImprovement.cs	(revision 17253)
@@ -21,5 +21,8 @@
 
 using System;
+using System.Collections.Generic;
+using System.Linq;
 using System.Threading;
+using HEAL.Attic;
 using HeuristicLab.Common;
 using HeuristicLab.Core;
@@ -29,5 +32,4 @@
 using HeuristicLab.Optimization;
 using HeuristicLab.Parameters;
-using HEAL.Attic;
 
 namespace HeuristicLab.Problems.PTSP {
@@ -70,10 +72,9 @@
     }
 
-    public ILookupParameter<DistanceMatrix> DistanceMatrixParameter {
-      get { return (ILookupParameter<DistanceMatrix>)Parameters["DistanceMatrix"]; }
+    public ILookupParameter<IProbabilisticTSPData> ProbabilisticTSPDataParameter {
+      get { return (ILookupParameter<IProbabilisticTSPData>)Parameters["PTSP Data"]; }
     }
-
-    public ILookupParameter<ItemList<BoolArray>> RealizationsParameter {
-      get { return (ILookupParameter<ItemList<BoolArray>>)Parameters["Realizations"]; }
+    public ILookupParameter<ReadOnlyItemList<BoolArray>> RealizationsParameter {
+      get { return (ILookupParameter<ReadOnlyItemList<BoolArray>>)Parameters["Realizations"]; }
     }
 
@@ -90,6 +91,6 @@
       Parameters.Add(new LookupParameter<DoubleValue>("Quality", "The quality value of the assignment."));
       Parameters.Add(new LookupParameter<BoolValue>("Maximization", "True if the problem should be maximized or minimized."));
-      Parameters.Add(new LookupParameter<DistanceMatrix>("DistanceMatrix", "The matrix which contains the distances between the cities."));
-      Parameters.Add(new LookupParameter<ItemList<BoolArray>>("Realizations", "The list of samples drawn from all possible stochastic instances."));
+      Parameters.Add(new LookupParameter<IProbabilisticTSPData>("PTSP Data", "The main parameters of the p-TSP."));
+      Parameters.Add(new LookupParameter<ReadOnlyItemList<BoolArray>>("Realizations", "The list of samples drawn from all possible stochastic instances."));
     }
 
@@ -98,7 +99,5 @@
     }
 
-    public static void Improve(Permutation assignment, DoubleMatrix distances, DoubleValue quality, IntValue localIterations, IntValue evaluatedSolutions, bool maximization, int maxIterations, ItemList<BoolArray> realizations, CancellationToken cancellation) {
-      var distanceM = (DistanceMatrix)distances;
-      Func<int, int, double> distance = (a, b) => distanceM[a, b];
+    public static void Improve(Permutation assignment, IProbabilisticTSPData data, DoubleValue quality, IntValue localIterations, IntValue evaluatedSolutions, bool maximization, int maxIterations, IEnumerable<BoolArray> realizations, CancellationToken cancellation) {
       for (var i = localIterations.Value; i < maxIterations; i++) {
         TwoPointFiveMove bestMove = null;
@@ -106,7 +105,7 @@
         var evaluations = 0.0;
         foreach (var move in ExhaustiveTwoPointFiveMoveGenerator.Generate(assignment)) {
-          var moveQuality = PTSPEstimatedTwoPointFiveMoveEvaluator.EvaluateMove(assignment, move, distance, realizations);
-          if (move.IsInvert) evaluations += realizations.Count * 4.0 / (assignment.Length * assignment.Length);
-          else evaluations += realizations.Count * 6.0 / (assignment.Length * assignment.Length);
+          var moveQuality = PTSPEstimatedTwoPointFiveMoveEvaluator.EvaluateMove(assignment, move, data, realizations);
+          if (move.IsInvert) evaluations += realizations.Count() * 4.0 / (assignment.Length * assignment.Length);
+          else evaluations += realizations.Count() * 6.0 / (assignment.Length * assignment.Length);
           if (maximization && moveQuality > bestQuality
             || !maximization && moveQuality < bestQuality) {
@@ -128,8 +127,8 @@
       var assignment = PermutationParameter.ActualValue;
       var maximization = MaximizationParameter.ActualValue.Value;
-      var distances = DistanceMatrixParameter.ActualValue;
       var quality = QualityParameter.ActualValue;
       var localIterations = LocalIterationsParameter.ActualValue;
       var evaluations = EvaluatedSolutionsParameter.ActualValue;
+      var data = ProbabilisticTSPDataParameter.ActualValue;
       var realizations = RealizationsParameter.ActualValue;
       if (localIterations == null) {
@@ -138,5 +137,5 @@
       }
 
-      Improve(assignment, distances, quality, localIterations, evaluations, maximization, maxIterations, realizations, CancellationToken);
+      Improve(assignment, data, quality, localIterations, evaluations, maximization, maxIterations, realizations, CancellationToken);
 
       localIterations.Value = 0;
Index: /branches/2521_ProblemRefactoring/HeuristicLab.Problems.PTSP/3.3/Interfaces/IAnalyticalPTSPMoveEvaluator.cs
===================================================================
--- /branches/2521_ProblemRefactoring/HeuristicLab.Problems.PTSP/3.3/Interfaces/IAnalyticalPTSPMoveEvaluator.cs	(revision 17252)
+++ /branches/2521_ProblemRefactoring/HeuristicLab.Problems.PTSP/3.3/Interfaces/IAnalyticalPTSPMoveEvaluator.cs	(revision 17253)
@@ -20,17 +20,11 @@
 #endregion
 
-using HeuristicLab.Core;
-using HeuristicLab.Data;
+using HEAL.Attic;
 using HeuristicLab.Encodings.PermutationEncoding;
 using HeuristicLab.Optimization;
-using HEAL.Attic;
 
 namespace HeuristicLab.Problems.PTSP {
-  [StorableType("D503E92D-9A85-46AC-ADAA-8A454B9E9C79")]
+  [StorableType("dea758f7-136a-469f-a486-ef6569fa0c74")]
   public interface IAnalyticalPTSPMoveEvaluator : IAnalyticalPTSPOperator, ISingleObjectiveMoveEvaluator, IPermutationMoveOperator {
-    ILookupParameter<DoubleMatrix> CoordinatesParameter { get; }
-    ILookupParameter<DistanceCalculator> DistanceCalculatorParameter { get; }
-    ILookupParameter<DistanceMatrix> DistanceMatrixParameter { get; }
-    ILookupParameter<BoolValue> UseDistanceMatrixParameter { get; }
   }
 }
Index: /branches/2521_ProblemRefactoring/HeuristicLab.Problems.PTSP/3.3/Interfaces/IAnalyticalPTSPOperator.cs
===================================================================
--- /branches/2521_ProblemRefactoring/HeuristicLab.Problems.PTSP/3.3/Interfaces/IAnalyticalPTSPOperator.cs	(revision 17252)
+++ /branches/2521_ProblemRefactoring/HeuristicLab.Problems.PTSP/3.3/Interfaces/IAnalyticalPTSPOperator.cs	(revision 17253)
@@ -20,12 +20,11 @@
 #endregion
 
+using HEAL.Attic;
 using HeuristicLab.Core;
-using HeuristicLab.Data;
-using HEAL.Attic;
 
 namespace HeuristicLab.Problems.PTSP {
-  [StorableType("1BB8344B-894B-48E9-9805-49938AE3F83F")]
+  [StorableType("2b0bd347-7bb6-449a-bbcf-24aa452abc0a")]
   public interface IAnalyticalPTSPOperator : IItem {
-    ILookupParameter<DoubleArray> ProbabilitiesParameter { get; }
+    ILookupParameter<IProbabilisticTSPData> ProbabilisticTSPDataParameter { get; }
   }
 }
Index: /branches/2521_ProblemRefactoring/HeuristicLab.Problems.PTSP/3.3/Interfaces/IEstimatedPTSPMoveEvaluator.cs
===================================================================
--- /branches/2521_ProblemRefactoring/HeuristicLab.Problems.PTSP/3.3/Interfaces/IEstimatedPTSPMoveEvaluator.cs	(revision 17252)
+++ /branches/2521_ProblemRefactoring/HeuristicLab.Problems.PTSP/3.3/Interfaces/IEstimatedPTSPMoveEvaluator.cs	(revision 17253)
@@ -20,17 +20,11 @@
 #endregion
 
-using HeuristicLab.Core;
-using HeuristicLab.Data;
+using HEAL.Attic;
 using HeuristicLab.Encodings.PermutationEncoding;
 using HeuristicLab.Optimization;
-using HEAL.Attic;
 
 namespace HeuristicLab.Problems.PTSP {
-  [StorableType("FECFFE5C-64EE-4615-A9FC-786F2B37143A")]
+  [StorableType("96103e8b-bfc4-4e42-a579-074bfdd8d589")]
   public interface IEstimatedPTSPMoveEvaluator : IEstimatedPTSPOperator, ISingleObjectiveMoveEvaluator, IPermutationMoveOperator {
-    ILookupParameter<DoubleMatrix> CoordinatesParameter { get; }
-    ILookupParameter<DistanceCalculator> DistanceCalculatorParameter { get; }
-    ILookupParameter<DistanceMatrix> DistanceMatrixParameter { get; }
-    ILookupParameter<BoolValue> UseDistanceMatrixParameter { get; }
   }
 }
Index: /branches/2521_ProblemRefactoring/HeuristicLab.Problems.PTSP/3.3/Interfaces/IEstimatedPTSPOperator.cs
===================================================================
--- /branches/2521_ProblemRefactoring/HeuristicLab.Problems.PTSP/3.3/Interfaces/IEstimatedPTSPOperator.cs	(revision 17252)
+++ /branches/2521_ProblemRefactoring/HeuristicLab.Problems.PTSP/3.3/Interfaces/IEstimatedPTSPOperator.cs	(revision 17253)
@@ -20,12 +20,13 @@
 #endregion
 
+using HEAL.Attic;
 using HeuristicLab.Core;
 using HeuristicLab.Data;
-using HEAL.Attic;
 
 namespace HeuristicLab.Problems.PTSP {
-  [StorableType("1998604C-41FF-4388-B413-8BD658D073E5")]
+  [StorableType("5bcc1ef1-b865-42be-8a63-e5f810c52d01")]
   public interface IEstimatedPTSPOperator : IItem {
-    ILookupParameter<ItemList<BoolArray>> RealizationsParameter { get; }
+    ILookupParameter<IProbabilisticTSPData> ProbabilisticTSPDataParameter { get; }
+    ILookupParameter<ReadOnlyItemList<BoolArray>> RealizationsParameter { get; }
   }
 }
Index: /branches/2521_ProblemRefactoring/HeuristicLab.Problems.PTSP/3.3/Moves/AnalyticalPTSPMoveEvaluator.cs
===================================================================
--- /branches/2521_ProblemRefactoring/HeuristicLab.Problems.PTSP/3.3/Moves/AnalyticalPTSPMoveEvaluator.cs	(revision 17252)
+++ /branches/2521_ProblemRefactoring/HeuristicLab.Problems.PTSP/3.3/Moves/AnalyticalPTSPMoveEvaluator.cs	(revision 17253)
@@ -20,5 +20,5 @@
 #endregion
 
-using System;
+using HEAL.Attic;
 using HeuristicLab.Common;
 using HeuristicLab.Core;
@@ -27,5 +27,4 @@
 using HeuristicLab.Operators;
 using HeuristicLab.Parameters;
-using HEAL.Attic;
 
 namespace HeuristicLab.Problems.PTSP {
@@ -41,16 +40,4 @@
       get { return (ILookupParameter<Permutation>)Parameters["Permutation"]; }
     }
-    public ILookupParameter<DoubleMatrix> CoordinatesParameter {
-      get { return (ILookupParameter<DoubleMatrix>)Parameters["Coordinates"]; }
-    }
-    public ILookupParameter<DistanceMatrix> DistanceMatrixParameter {
-      get { return (ILookupParameter<DistanceMatrix>)Parameters["DistanceMatrix"]; }
-    }
-    public ILookupParameter<BoolValue> UseDistanceMatrixParameter {
-      get { return (ILookupParameter<BoolValue>)Parameters["UseDistanceMatrix"]; }
-    }
-    public ILookupParameter<DoubleArray> ProbabilitiesParameter {
-      get { return (ILookupParameter<DoubleArray>)Parameters["Probabilities"]; }
-    }
     public ILookupParameter<DoubleValue> QualityParameter {
       get { return (ILookupParameter<DoubleValue>)Parameters["Quality"]; }
@@ -59,6 +46,6 @@
       get { return (ILookupParameter<DoubleValue>)Parameters["MoveQuality"]; }
     }
-    public ILookupParameter<DistanceCalculator> DistanceCalculatorParameter {
-      get { return (ILookupParameter<DistanceCalculator>)Parameters["DistanceCalculator"]; }
+    public ILookupParameter<IProbabilisticTSPData> ProbabilisticTSPDataParameter {
+      get { return (ILookupParameter<IProbabilisticTSPData>)Parameters["PTSP Data"]; }
     }
 
@@ -69,30 +56,15 @@
       : base() {
       Parameters.Add(new LookupParameter<Permutation>("Permutation", "The solution as permutation."));
-      Parameters.Add(new LookupParameter<DoubleMatrix>("Coordinates", "The city's coordinates."));
-      Parameters.Add(new LookupParameter<DistanceMatrix>("DistanceMatrix", "The matrix which contains the distances between the cities."));
-      Parameters.Add(new LookupParameter<BoolValue>("UseDistanceMatrix", "True if a distance matrix should be calculated (if it does not exist already) and used for evaluation, otherwise false."));
-      Parameters.Add(new LookupParameter<DoubleArray>("Probabilities", "The list of probabilities for each city to appear."));
       Parameters.Add(new LookupParameter<DoubleValue>("Quality", "The quality of a TSP solution."));
       Parameters.Add(new LookupParameter<DoubleValue>("MoveQuality", "The evaluated quality of a move on a TSP solution."));
-      Parameters.Add(new LookupParameter<DistanceCalculator>("DistanceCalculator", "The class that can compute distances between coordinates."));
+      Parameters.Add(new LookupParameter<IProbabilisticTSPData>("PTSP Data", "The main parameters of the p-TSP."));
     }
 
     public override IOperation Apply() {
       var permutation = PermutationParameter.ActualValue;
-      var coordinates = CoordinatesParameter.ActualValue;
-      var probabilities = ProbabilitiesParameter.ActualValue;
-      Func<int, int, double> distance = null;
-      if (UseDistanceMatrixParameter.ActualValue.Value) {
-        var distanceMatrix = DistanceMatrixParameter.ActualValue;
-        if (distanceMatrix == null) throw new InvalidOperationException("The distance matrix has not been calculated.");
-        distance = (a, b) => distanceMatrix[a, b];
-      } else {
-        if (coordinates == null) throw new InvalidOperationException("No coordinates were given.");
-        var distanceCalculator = DistanceCalculatorParameter.ActualValue;
-        if (distanceCalculator == null) throw new InvalidOperationException("Distance calculator is null!");
-        distance = (a, b) => distanceCalculator.Calculate(a, b, coordinates);
-      }
+      var data = ProbabilisticTSPDataParameter.ActualValue;
+
       // here moves are not delta-evaluated
-      var newQuality = EvaluateMove(permutation, distance, probabilities);
+      var newQuality = EvaluateMove(permutation, data);
       var moveQuality = MoveQualityParameter.ActualValue;
       if (moveQuality == null) MoveQualityParameter.ActualValue = new DoubleValue(newQuality);
@@ -102,5 +74,5 @@
     }
 
-    protected abstract double EvaluateMove(Permutation permutation, Func<int, int, double> distance, DoubleArray probabilities);
+    protected abstract double EvaluateMove(Permutation tour, IProbabilisticTSPData data);
   }
 }
Index: /branches/2521_ProblemRefactoring/HeuristicLab.Problems.PTSP/3.3/Moves/EstimatedPTSPMoveEvaluator.cs
===================================================================
--- /branches/2521_ProblemRefactoring/HeuristicLab.Problems.PTSP/3.3/Moves/EstimatedPTSPMoveEvaluator.cs	(revision 17252)
+++ /branches/2521_ProblemRefactoring/HeuristicLab.Problems.PTSP/3.3/Moves/EstimatedPTSPMoveEvaluator.cs	(revision 17253)
@@ -20,5 +20,5 @@
 #endregion
 
-using System;
+using HEAL.Attic;
 using HeuristicLab.Common;
 using HeuristicLab.Core;
@@ -27,5 +27,4 @@
 using HeuristicLab.Operators;
 using HeuristicLab.Parameters;
-using HEAL.Attic;
 
 namespace HeuristicLab.Problems.PTSP {
@@ -41,15 +40,9 @@
       get { return (ILookupParameter<Permutation>)Parameters["Permutation"]; }
     }
-    public ILookupParameter<DoubleMatrix> CoordinatesParameter {
-      get { return (ILookupParameter<DoubleMatrix>)Parameters["Coordinates"]; }
+    public ILookupParameter<IProbabilisticTSPData> ProbabilisticTSPDataParameter {
+      get { return (ILookupParameter<IProbabilisticTSPData>)Parameters["PTSP Data"]; }
     }
-    public ILookupParameter<DistanceMatrix> DistanceMatrixParameter {
-      get { return (ILookupParameter<DistanceMatrix>)Parameters["DistanceMatrix"]; }
-    }
-    public ILookupParameter<BoolValue> UseDistanceMatrixParameter {
-      get { return (ILookupParameter<BoolValue>)Parameters["UseDistanceMatrix"]; }
-    }
-    public ILookupParameter<ItemList<BoolArray>> RealizationsParameter {
-      get { return (ILookupParameter<ItemList<BoolArray>>)Parameters["Realizations"]; }
+    public ILookupParameter<ReadOnlyItemList<BoolArray>> RealizationsParameter {
+      get { return (ILookupParameter<ReadOnlyItemList<BoolArray>>)Parameters["Realizations"]; }
     }
     public ILookupParameter<DoubleValue> QualityParameter {
@@ -58,7 +51,4 @@
     public ILookupParameter<DoubleValue> MoveQualityParameter {
       get { return (ILookupParameter<DoubleValue>)Parameters["MoveQuality"]; }
-    }
-    public ILookupParameter<DistanceCalculator> DistanceCalculatorParameter {
-      get { return (ILookupParameter<DistanceCalculator>)Parameters["DistanceCalculator"]; }
     }
 
@@ -69,29 +59,15 @@
       : base() {
       Parameters.Add(new LookupParameter<Permutation>("Permutation", "The solution as permutation."));
-      Parameters.Add(new LookupParameter<DoubleMatrix>("Coordinates", "The city's coordinates."));
-      Parameters.Add(new LookupParameter<DistanceMatrix>("DistanceMatrix", "The matrix which contains the distances between the cities."));
-      Parameters.Add(new LookupParameter<BoolValue>("UseDistanceMatrix", "True if a distance matrix should be calculated (if it does not exist already) and used for evaluation, otherwise false."));
-      Parameters.Add(new LookupParameter<ItemList<BoolArray>>("Realizations", "The list of samples drawn from all possible stochastic instances."));
+      Parameters.Add(new LookupParameter<IProbabilisticTSPData>("PTSP Data", "The main parameters of the p-TSP."));
+      Parameters.Add(new LookupParameter<ReadOnlyItemList<BoolArray>>("Realizations", "The list of samples drawn from all possible stochastic instances."));
       Parameters.Add(new LookupParameter<DoubleValue>("Quality", "The quality of a TSP solution."));
       Parameters.Add(new LookupParameter<DoubleValue>("MoveQuality", "The evaluated quality of a move on a TSP solution."));
-      Parameters.Add(new LookupParameter<DistanceCalculator>("DistanceCalculator", "The class that can compute distances between coordinates."));
     }
 
     public override IOperation Apply() {
       var permutation = PermutationParameter.ActualValue;
-      var coordinates = CoordinatesParameter.ActualValue;
       var realizations = RealizationsParameter.ActualValue;
-      Func<int, int, double> distance = null;
-      if (UseDistanceMatrixParameter.ActualValue.Value) {
-        var distanceMatrix = DistanceMatrixParameter.ActualValue;
-        if (distanceMatrix == null) throw new InvalidOperationException("The distance matrix has not been calculated.");
-        distance = (a, b) => distanceMatrix[a, b];
-      } else {
-        if (coordinates == null) throw new InvalidOperationException("No coordinates were given.");
-        var distanceCalculator = DistanceCalculatorParameter.ActualValue;
-        if (distanceCalculator == null) throw new InvalidOperationException("Distance calculator is null!");
-        distance = (a, b) => distanceCalculator.Calculate(a, b, coordinates);
-      }
-      var relativeQualityDifference = EvaluateMove(permutation, distance, realizations);
+      var data = ProbabilisticTSPDataParameter.ActualValue;
+      var relativeQualityDifference = EvaluateMove(permutation, data, realizations);
       var moveQuality = MoveQualityParameter.ActualValue;
       if (moveQuality == null) MoveQualityParameter.ActualValue = new DoubleValue(QualityParameter.ActualValue.Value + relativeQualityDifference);
@@ -100,5 +76,5 @@
     }
 
-    protected abstract double EvaluateMove(Permutation permutation, Func<int, int, double> distance, ItemList<BoolArray> realizations);
+    protected abstract double EvaluateMove(Permutation tour, IProbabilisticTSPData data, ReadOnlyItemList<BoolArray> realizations);
   }
 }
Index: /branches/2521_ProblemRefactoring/HeuristicLab.Problems.PTSP/3.3/Moves/OneShift/PTSPAnalyticalInsertionMoveEvaluator.cs
===================================================================
--- /branches/2521_ProblemRefactoring/HeuristicLab.Problems.PTSP/3.3/Moves/OneShift/PTSPAnalyticalInsertionMoveEvaluator.cs	(revision 17252)
+++ /branches/2521_ProblemRefactoring/HeuristicLab.Problems.PTSP/3.3/Moves/OneShift/PTSPAnalyticalInsertionMoveEvaluator.cs	(revision 17253)
@@ -20,11 +20,9 @@
 #endregion
 
-using System;
+using HEAL.Attic;
 using HeuristicLab.Common;
 using HeuristicLab.Core;
-using HeuristicLab.Data;
 using HeuristicLab.Encodings.PermutationEncoding;
 using HeuristicLab.Parameters;
-using HEAL.Attic;
 
 namespace HeuristicLab.Problems.PTSP {
@@ -49,12 +47,12 @@
     }
 
-    public static double EvaluateMove(Permutation tour, TranslocationMove move, Func<int, int, double> distance, DoubleArray probabilities) {
+    public static double EvaluateMove(Permutation tour, TranslocationMove move, IProbabilisticTSPData data) {
       var afterMove = (Permutation)tour.Clone();
       TranslocationManipulator.Apply(afterMove, move.Index1, move.Index1, move.Index3);
-      return AnalyticalProbabilisticTravelingSalesmanProblem.Evaluate(afterMove, distance, probabilities);
+      return AnalyticalPTSP.Evaluate(afterMove, data);
     }
 
-    protected override double EvaluateMove(Permutation tour, Func<int, int, double> distance, DoubleArray probabilities) {
-      return EvaluateMove(tour, TranslocationMoveParameter.ActualValue, distance, probabilities);
+    protected override double EvaluateMove(Permutation tour, IProbabilisticTSPData data) {
+      return EvaluateMove(tour, TranslocationMoveParameter.ActualValue, data);
     }
   }
Index: /branches/2521_ProblemRefactoring/HeuristicLab.Problems.PTSP/3.3/Moves/OneShift/PTSPEstimatedInsertionMoveEvaluator.cs
===================================================================
--- /branches/2521_ProblemRefactoring/HeuristicLab.Problems.PTSP/3.3/Moves/OneShift/PTSPEstimatedInsertionMoveEvaluator.cs	(revision 17252)
+++ /branches/2521_ProblemRefactoring/HeuristicLab.Problems.PTSP/3.3/Moves/OneShift/PTSPEstimatedInsertionMoveEvaluator.cs	(revision 17253)
@@ -21,4 +21,6 @@
 
 using System;
+using System.Collections.Generic;
+using HEAL.Attic;
 using HeuristicLab.Common;
 using HeuristicLab.Core;
@@ -26,5 +28,4 @@
 using HeuristicLab.Encodings.PermutationEncoding;
 using HeuristicLab.Parameters;
-using HEAL.Attic;
 
 namespace HeuristicLab.Problems.PTSP {
@@ -49,5 +50,5 @@
     }
 
-    public static double EvaluateMove(Permutation tour, TranslocationMove move, Func<int, int, double> distance, ItemList<BoolArray> realizations) {
+    public static double EvaluateMove(Permutation tour, TranslocationMove move, IProbabilisticTSPData data, IEnumerable<BoolArray> realizations) {
       var afterMove = (Permutation)tour.Clone();
       TranslocationManipulator.Apply(afterMove, move.Index1, move.Index1, move.Index3);
@@ -93,4 +94,5 @@
       }
       int[] aPosteriori = new int[12];
+      var count = 0;
       foreach (var realization in realizations) {
         for (int i = 0; i < edges.Length; i++) {
@@ -124,11 +126,12 @@
           !(aPosteriori[2] == aPosteriori[4] && aPosteriori[3] == aPosteriori[5])) {
           // compute cost difference between the two a posteriori solutions
-          moveQuality = moveQuality + distance(aPosteriori[6], aPosteriori[7]) + distance(aPosteriori[8], aPosteriori[9]) + distance(aPosteriori[10], aPosteriori[11]);
-          moveQuality = moveQuality - distance(aPosteriori[0], aPosteriori[1]) - distance(aPosteriori[2], aPosteriori[3]) - distance(aPosteriori[4], aPosteriori[5]);
+          moveQuality = moveQuality + data.GetDistance(aPosteriori[6], aPosteriori[7]) + data.GetDistance(aPosteriori[8], aPosteriori[9]) + data.GetDistance(aPosteriori[10], aPosteriori[11]);
+          moveQuality = moveQuality - data.GetDistance(aPosteriori[0], aPosteriori[1]) - data.GetDistance(aPosteriori[2], aPosteriori[3]) - data.GetDistance(aPosteriori[4], aPosteriori[5]);
         }
         Array.Clear(aPosteriori, 0, aPosteriori.Length);
+        count++;
       }
       // return average of cost differences
-      return moveQuality / realizations.Count;
+      return moveQuality / count;
     }
 
@@ -149,6 +152,6 @@
     }
 
-    protected override double EvaluateMove(Permutation tour, Func<int, int, double> distance, ItemList<BoolArray> realizations) {
-      return EvaluateMove(tour, TranslocationMoveParameter.ActualValue, distance, realizations);
+    protected override double EvaluateMove(Permutation tour, IProbabilisticTSPData data, ReadOnlyItemList<BoolArray> realizations) {
+      return EvaluateMove(tour, TranslocationMoveParameter.ActualValue, data, realizations);
     }
   }
Index: /branches/2521_ProblemRefactoring/HeuristicLab.Problems.PTSP/3.3/Moves/TwoOpt/PTSPAnalyticalInversionMoveEvaluator.cs
===================================================================
--- /branches/2521_ProblemRefactoring/HeuristicLab.Problems.PTSP/3.3/Moves/TwoOpt/PTSPAnalyticalInversionMoveEvaluator.cs	(revision 17252)
+++ /branches/2521_ProblemRefactoring/HeuristicLab.Problems.PTSP/3.3/Moves/TwoOpt/PTSPAnalyticalInversionMoveEvaluator.cs	(revision 17253)
@@ -20,11 +20,9 @@
 #endregion
 
-using System;
+using HEAL.Attic;
 using HeuristicLab.Common;
 using HeuristicLab.Core;
-using HeuristicLab.Data;
 using HeuristicLab.Encodings.PermutationEncoding;
 using HeuristicLab.Parameters;
-using HEAL.Attic;
 
 namespace HeuristicLab.Problems.PTSP {
@@ -49,12 +47,12 @@
     }
 
-    public static double EvaluateMove(Permutation tour, InversionMove move, Func<int, int, double> distance, DoubleArray probabilities) {
+    public static double EvaluateMove(Permutation tour, InversionMove move, IProbabilisticTSPData data) {
       var afterMove = (Permutation)tour.Clone();
       InversionManipulator.Apply(afterMove, move.Index1, move.Index2);
-      return AnalyticalProbabilisticTravelingSalesmanProblem.Evaluate(afterMove, distance, probabilities);
+      return AnalyticalPTSP.Evaluate(afterMove, data);
     }
 
-    protected override double EvaluateMove(Permutation tour, Func<int, int, double> distance, DoubleArray probabilities) {
-      return EvaluateMove(tour, InversionMoveParameter.ActualValue, distance, probabilities);
+    protected override double EvaluateMove(Permutation tour, IProbabilisticTSPData data) {
+      return EvaluateMove(tour, InversionMoveParameter.ActualValue, data);
     }
   }
Index: /branches/2521_ProblemRefactoring/HeuristicLab.Problems.PTSP/3.3/Moves/TwoOpt/PTSPEstimatedInversionMoveEvaluator.cs
===================================================================
--- /branches/2521_ProblemRefactoring/HeuristicLab.Problems.PTSP/3.3/Moves/TwoOpt/PTSPEstimatedInversionMoveEvaluator.cs	(revision 17252)
+++ /branches/2521_ProblemRefactoring/HeuristicLab.Problems.PTSP/3.3/Moves/TwoOpt/PTSPEstimatedInversionMoveEvaluator.cs	(revision 17253)
@@ -21,4 +21,6 @@
 
 using System;
+using System.Collections.Generic;
+using HEAL.Attic;
 using HeuristicLab.Common;
 using HeuristicLab.Core;
@@ -26,5 +28,4 @@
 using HeuristicLab.Encodings.PermutationEncoding;
 using HeuristicLab.Parameters;
-using HEAL.Attic;
 
 namespace HeuristicLab.Problems.PTSP {
@@ -49,5 +50,5 @@
     }
 
-    public static double EvaluateMove(Permutation tour, InversionMove move, Func<int, int, double> distance, ItemList<BoolArray> realizations) {
+    public static double EvaluateMove(Permutation tour, InversionMove move, IProbabilisticTSPData data, IEnumerable<BoolArray> realizations) {
       double moveQuality = 0;
       var edges = new int[4];
@@ -64,4 +65,5 @@
       if (indices[3] == tour.Length + 1) indices[3] = 0;
       var aPosteriori = new int[4];
+      var count = 0;
       foreach (var realization in realizations) {
         for (var i = 0; i < edges.Length; i++) {
@@ -87,15 +89,16 @@
         // compute cost difference between the two a posteriori solutions
         if (!(aPosteriori[0] == aPosteriori[2] && aPosteriori[1] == aPosteriori[3])) {
-          moveQuality = moveQuality + distance(aPosteriori[0], aPosteriori[2]) + distance(aPosteriori[1], aPosteriori[3])
-            - distance(aPosteriori[0], aPosteriori[1]) - distance(aPosteriori[2], aPosteriori[3]);
+          moveQuality = moveQuality + data.GetDistance(aPosteriori[0], aPosteriori[2]) + data.GetDistance(aPosteriori[1], aPosteriori[3])
+            - data.GetDistance(aPosteriori[0], aPosteriori[1]) - data.GetDistance(aPosteriori[2], aPosteriori[3]);
         }
         Array.Clear(aPosteriori, 0, aPosteriori.Length);
+        count++;
       }
       // return average of cost differences
-      return moveQuality / realizations.Count;
+      return moveQuality / count;
     }
 
-    protected override double EvaluateMove(Permutation tour, Func<int, int, double> distance, ItemList<BoolArray> realizations) {
-      return EvaluateMove(tour, InversionMoveParameter.ActualValue, distance, realizations);
+    protected override double EvaluateMove(Permutation tour, IProbabilisticTSPData data, ReadOnlyItemList<BoolArray> realizations) {
+      return EvaluateMove(tour, InversionMoveParameter.ActualValue, data, realizations);
     }
   }
Index: /branches/2521_ProblemRefactoring/HeuristicLab.Problems.PTSP/3.3/Moves/TwoPointFiveOpt/PTSPAnalyticalTwoPointFiveMoveEvaluator.cs
===================================================================
--- /branches/2521_ProblemRefactoring/HeuristicLab.Problems.PTSP/3.3/Moves/TwoPointFiveOpt/PTSPAnalyticalTwoPointFiveMoveEvaluator.cs	(revision 17252)
+++ /branches/2521_ProblemRefactoring/HeuristicLab.Problems.PTSP/3.3/Moves/TwoPointFiveOpt/PTSPAnalyticalTwoPointFiveMoveEvaluator.cs	(revision 17253)
@@ -20,11 +20,9 @@
 #endregion
 
-using System;
+using HEAL.Attic;
 using HeuristicLab.Common;
 using HeuristicLab.Core;
-using HeuristicLab.Data;
 using HeuristicLab.Encodings.PermutationEncoding;
 using HeuristicLab.Parameters;
-using HEAL.Attic;
 
 namespace HeuristicLab.Problems.PTSP {
@@ -49,15 +47,15 @@
     }
 
-    protected override double EvaluateMove(Permutation permutation, Func<int, int, double> distance, DoubleArray probabilities) {
-      return EvaluateMove(permutation, TwoPointFiveMoveParameter.ActualValue, distance, probabilities);
+    protected override double EvaluateMove(Permutation permutation, IProbabilisticTSPData data) {
+      return EvaluateMove(permutation, TwoPointFiveMoveParameter.ActualValue, data);
     }
 
-    public static double EvaluateMove(Permutation permutation, TwoPointFiveMove move, Func<int, int, double> distance, DoubleArray probabilities) {
+    public static double EvaluateMove(Permutation permutation, TwoPointFiveMove move, IProbabilisticTSPData data) {
       if (move.IsInvert) {
         return PTSPAnalyticalInversionMoveEvaluator.EvaluateMove(permutation,
-          new InversionMove(move.Index1, move.Index2, move.Permutation), distance, probabilities);
+          new InversionMove(move.Index1, move.Index2, move.Permutation), data);
       } else {
         return PTSPAnalyticalInsertionMoveEvaluator.EvaluateMove(permutation,
-          new TranslocationMove(move.Index1, move.Index1, move.Index2), distance, probabilities);
+          new TranslocationMove(move.Index1, move.Index1, move.Index2), data);
       }
     }
Index: /branches/2521_ProblemRefactoring/HeuristicLab.Problems.PTSP/3.3/Moves/TwoPointFiveOpt/PTSPEstimatedTwoPointFiveMoveEvaluator.cs
===================================================================
--- /branches/2521_ProblemRefactoring/HeuristicLab.Problems.PTSP/3.3/Moves/TwoPointFiveOpt/PTSPEstimatedTwoPointFiveMoveEvaluator.cs	(revision 17252)
+++ /branches/2521_ProblemRefactoring/HeuristicLab.Problems.PTSP/3.3/Moves/TwoPointFiveOpt/PTSPEstimatedTwoPointFiveMoveEvaluator.cs	(revision 17253)
@@ -20,5 +20,6 @@
 #endregion
 
-using System;
+using System.Collections.Generic;
+using HEAL.Attic;
 using HeuristicLab.Common;
 using HeuristicLab.Core;
@@ -26,5 +27,4 @@
 using HeuristicLab.Encodings.PermutationEncoding;
 using HeuristicLab.Parameters;
-using HEAL.Attic;
 
 namespace HeuristicLab.Problems.PTSP {
@@ -49,15 +49,15 @@
     }
 
-    protected override double EvaluateMove(Permutation permutation, Func<int, int, double> distance, ItemList<BoolArray> realizations) {
-      return EvaluateMove(permutation, TwoPointFiveMoveParameter.ActualValue, distance, realizations);
+    protected override double EvaluateMove(Permutation permutation, IProbabilisticTSPData data, ReadOnlyItemList<BoolArray> realizations) {
+      return EvaluateMove(permutation, TwoPointFiveMoveParameter.ActualValue, data, realizations);
     }
 
-    public static double EvaluateMove(Permutation permutation, TwoPointFiveMove move, Func<int, int, double> distance, ItemList<BoolArray> realizations) {
+    public static double EvaluateMove(Permutation permutation, TwoPointFiveMove move, IProbabilisticTSPData data, IEnumerable<BoolArray> realizations) {
       if (move.IsInvert) {
         return PTSPEstimatedInversionMoveEvaluator.EvaluateMove(permutation,
-          new InversionMove(move.Index1, move.Index2, move.Permutation), distance, realizations);
+          new InversionMove(move.Index1, move.Index2, move.Permutation), data, realizations);
       } else {
         return PTSPEstimatedInsertionMoveEvaluator.EvaluateMove(permutation,
-          new TranslocationMove(move.Index1, move.Index1, move.Index2), distance, realizations);
+          new TranslocationMove(move.Index1, move.Index1, move.Index2), data, realizations);
       }
     }
Index: /branches/2521_ProblemRefactoring/HeuristicLab.Problems.PTSP/3.3/PTSP.cs
===================================================================
--- /branches/2521_ProblemRefactoring/HeuristicLab.Problems.PTSP/3.3/PTSP.cs	(revision 17252)
+++ /branches/2521_ProblemRefactoring/HeuristicLab.Problems.PTSP/3.3/PTSP.cs	(revision 17253)
@@ -22,5 +22,5 @@
 using System;
 using System.Linq;
-using HeuristicLab.Analysis;
+using HEAL.Attic;
 using HeuristicLab.Common;
 using HeuristicLab.Core;
@@ -28,65 +28,32 @@
 using HeuristicLab.Encodings.PermutationEncoding;
 using HeuristicLab.Optimization;
-using HeuristicLab.Optimization.Operators;
 using HeuristicLab.Parameters;
-using HEAL.Attic;
 using HeuristicLab.Problems.Instances;
+using HeuristicLab.Problems.TravelingSalesman;
+using HeuristicLab.Random;
 
 namespace HeuristicLab.Problems.PTSP {
-  [Item("Probabilistic Traveling Salesman Problem (PTSP)", "Represents a Probabilistic Traveling Salesman Problem.")]
-  [StorableType("4CB8ACF3-C3D4-4CC6-BB1F-986BDE16B30A")]
-  public abstract class ProbabilisticTravelingSalesmanProblem : SingleObjectiveBasicProblem<PermutationEncoding>,
-  IProblemInstanceConsumer<PTSPData> {
+  [Item("Probabilistic TSP (p-TSP)", "Represents a Probabilistic Traveling Salesman Problem.")]
+  [StorableType("86041a8c-14e6-46e1-b20f-566892c871f6")]
+  public abstract class ProbabilisticTSP : PermutationProblem,
+      IProblemInstanceConsumer<PTSPData> {
     protected bool SuppressEvents { get; set; }
 
-    private static readonly int DistanceMatrixSizeLimit = 1000;
+    public static int DistanceMatrixSizeLimit = 1000;
 
     #region Parameter Properties
-    public OptionalValueParameter<DoubleMatrix> CoordinatesParameter {
-      get { return (OptionalValueParameter<DoubleMatrix>)Parameters["Coordinates"]; }
-    }
-    public OptionalValueParameter<DistanceCalculator> DistanceCalculatorParameter {
-      get { return (OptionalValueParameter<DistanceCalculator>)Parameters["DistanceCalculator"]; }
-    }
-    public OptionalValueParameter<DistanceMatrix> DistanceMatrixParameter {
-      get { return (OptionalValueParameter<DistanceMatrix>)Parameters["DistanceMatrix"]; }
-    }
-    public IFixedValueParameter<BoolValue> UseDistanceMatrixParameter {
-      get { return (IFixedValueParameter<BoolValue>)Parameters["UseDistanceMatrix"]; }
-    }
-    public OptionalValueParameter<Permutation> BestKnownSolutionParameter {
-      get { return (OptionalValueParameter<Permutation>)Parameters["BestKnownSolution"]; }
-    }
-    public IValueParameter<DoubleArray> ProbabilitiesParameter {
-      get { return (IValueParameter<DoubleArray>)Parameters["Probabilities"]; }
-    }
+    [Storable] public ValueParameter<IProbabilisticTSPData> PTSPDataParameter { get; private set; }
+    [Storable] public OptionalValueParameter<ITSPSolution> BestKnownSolutionParameter { get; private set; }
     #endregion
 
     #region Properties
-    public DoubleMatrix Coordinates {
-      get { return CoordinatesParameter.Value; }
-      set { CoordinatesParameter.Value = value; }
+    public IProbabilisticTSPData ProbabilisticTSPData {
+      get { return PTSPDataParameter.Value; }
+      set { PTSPDataParameter.Value = value; }
     }
-    public DistanceCalculator DistanceCalculator {
-      get { return DistanceCalculatorParameter.Value; }
-      set { DistanceCalculatorParameter.Value = value; }
-    }
-    public DistanceMatrix DistanceMatrix {
-      get { return DistanceMatrixParameter.Value; }
-      set { DistanceMatrixParameter.Value = value; }
-    }
-    public bool UseDistanceMatrix {
-      get { return UseDistanceMatrixParameter.Value.Value; }
-      set { UseDistanceMatrixParameter.Value.Value = value; }
-    }
-    public Permutation BestKnownSolution {
+    public ITSPSolution BestKnownSolution {
       get { return BestKnownSolutionParameter.Value; }
       set { BestKnownSolutionParameter.Value = value; }
     }
-    public DoubleArray Probabilities {
-      get { return ProbabilitiesParameter.Value; }
-      set { ProbabilitiesParameter.Value = value; }
-    }
-
     #endregion
 
@@ -96,166 +63,109 @@
 
     [StorableConstructor]
-    protected ProbabilisticTravelingSalesmanProblem(StorableConstructorFlag _) : base(_) { }
-    protected ProbabilisticTravelingSalesmanProblem(ProbabilisticTravelingSalesmanProblem original, Cloner cloner)
+    protected ProbabilisticTSP(StorableConstructorFlag _) : base(_) { }
+    protected ProbabilisticTSP(ProbabilisticTSP original, Cloner cloner)
       : base(original, cloner) {
-      RegisterEventHandlers();
+      PTSPDataParameter = cloner.Clone(original.PTSPDataParameter);
+      BestKnownSolutionParameter = cloner.Clone(original.BestKnownSolutionParameter);
     }
-    protected ProbabilisticTravelingSalesmanProblem() {
-      Parameters.Add(new OptionalValueParameter<DoubleMatrix>("Coordinates", "The x- and y-Coordinates of the cities."));
-      Parameters.Add(new OptionalValueParameter<DistanceCalculator>("DistanceCalculator", "Calculates the distance between two rows in the coordinates matrix."));
-      Parameters.Add(new OptionalValueParameter<DistanceMatrix>("DistanceMatrix", "The matrix which contains the distances between the cities."));
-      Parameters.Add(new FixedValueParameter<BoolValue>("UseDistanceMatrix", "True if the coordinates based evaluators should calculate the distance matrix from the coordinates and use it for evaluation similar to the distance matrix evaluator, otherwise false.", new BoolValue(true)));
-      Parameters.Add(new OptionalValueParameter<Permutation>("BestKnownSolution", "The best known solution of this TSP instance."));
-      Parameters.Add(new ValueParameter<DoubleArray>("Probabilities", "This list describes for each city the probability of appearing in a realized instance."));
+    protected ProbabilisticTSP() {
+      Parameters.Add(PTSPDataParameter = new ValueParameter<IProbabilisticTSPData>("PTSP Data", "The main parameters for the p-TSP."));
+      Parameters.Add(BestKnownSolutionParameter = new OptionalValueParameter<ITSPSolution>("BestKnownSolution", "The best known solution of this p-TSP instance."));
 
-      var coordinates = new DoubleMatrix(new double[,] {
-        { 100, 100 }, { 100, 200 }, { 100, 300 }, { 100, 400 },
-        { 200, 100 }, { 200, 200 }, { 200, 300 }, { 200, 400 },
-        { 300, 100 }, { 300, 200 }, { 300, 300 }, { 300, 400 },
-        { 400, 100 }, { 400, 200 }, { 400, 300 }, { 400, 400 }
-      });
-      Coordinates = coordinates;
-      Encoding.Length = coordinates.Rows;
-      DistanceCalculator = new EuclideanDistance();
-      DistanceMatrix = new DistanceMatrix(CalculateDistances());
-      Probabilities = new DoubleArray(Enumerable.Range(0, coordinates.Rows).Select(x => 0.5).ToArray());
-
-      InitializeOperators();
-      Parameterize();
-      RegisterEventHandlers();
-    }
-
-    private void InitializeOperators() {
-      Operators.Add(new HammingSimilarityCalculator());
-      Operators.Add(new QualitySimilarityCalculator());
-      Operators.Add(new PopulationSimilarityAnalyzer(Operators.OfType<ISolutionSimilarityCalculator>()));
-    }
-
-    [StorableHook(HookType.AfterDeserialization)]
-    private void AfterDeserialization() {
-      RegisterEventHandlers();
+      ProbabilisticTSPData = new MatrixProbabilisticTSPData();
+      Encoding.Length = ProbabilisticTSPData.Cities;
     }
 
     protected override void OnEncodingChanged() {
       base.OnEncodingChanged();
-      Encoding.Length = Coordinates.Rows;
-      Parameterize();
+      Encoding.Length = ProbabilisticTSPData.Cities;
     }
 
-    private void RegisterEventHandlers() {
-      CoordinatesParameter.ValueChanged += CoordinatesParameterOnValueChanged;
-      if (Coordinates != null) {
-        Coordinates.RowsChanged += CoordinatesOnChanged;
-        Coordinates.ItemChanged += CoordinatesOnChanged;
+    public override void Analyze(Permutation[] solutions, double[] qualities, ResultCollection results, IRandom random) {
+      base.Analyze(solutions, qualities, results, random);
+      var max = Maximization;
+
+      var i = !max ? qualities.Select((x, index) => new { index, x }).OrderBy(x => x).First().index
+                   : qualities.Select((x, index) => new { index, x }).OrderByDescending(x => x).First().index;
+
+      if (double.IsNaN(BestKnownQuality) ||
+          max && qualities[i] > BestKnownQuality ||
+          !max && qualities[i] < BestKnownQuality) {
+        BestKnownQuality = qualities[i];
+        BestKnownSolution = ProbabilisticTSPData.GetSolution((Permutation)solutions[i].Clone(), qualities[i]);
       }
-      UseDistanceMatrixParameter.Value.ValueChanged += UseDistanceMatrixValueChanged;
-      DistanceCalculatorParameter.ValueChanged += DistanceCalculatorParameterOnValueChanged;
-    }
 
-    private void CoordinatesParameterOnValueChanged(object sender, EventArgs eventArgs) {
-      if (Coordinates != null) {
-        Coordinates.RowsChanged += CoordinatesOnChanged;
-        Coordinates.ItemChanged += CoordinatesOnChanged;
-      }
-      if (SuppressEvents) return;
-      UpdateInstance();
-    }
-
-    private void CoordinatesOnChanged(object sender, EventArgs eventArgs) {
-      if (SuppressEvents) return;
-      UpdateInstance();
-    }
-
-    private void UseDistanceMatrixValueChanged(object sender, EventArgs eventArgs) {
-      if (SuppressEvents) return;
-      UpdateInstance();
-    }
-
-    private void DistanceCalculatorParameterOnValueChanged(object sender, EventArgs eventArgs) {
-      if (SuppressEvents) return;
-      UpdateInstance();
-    }
-
-    public override double Evaluate(Individual individual, IRandom random) {
-      return Evaluate(individual.Permutation(), random);
-    }
-
-    public abstract double Evaluate(Permutation tour, IRandom random);
-
-    public double[,] CalculateDistances() {
-      var coords = Coordinates;
-      var len = coords.Rows;
-      var dist = DistanceCalculator;
-
-      var matrix = new double[len, len];
-      for (var i = 0; i < len - 1; i++)
-        for (var j = i + 1; j < len; j++)
-          matrix[i, j] = matrix[j, i] = dist.Calculate(i, j, coords);
-
-      return matrix;
+      IResult bestSolutionResult;
+      if (results.TryGetValue("Best p-TSP Solution", out bestSolutionResult)) {
+        var bestSolution = bestSolutionResult.Value as ITSPSolution;
+        if (bestSolution == null || Maximization && bestSolution.TourLength.Value < qualities[i]
+          || !Maximization && bestSolution.TourLength.Value > qualities[i]) {
+          bestSolutionResult.Value = ProbabilisticTSPData.GetSolution(solutions[i], qualities[i]);
+        }
+      } else results.Add(new Result("Best p-TSP Solution", ProbabilisticTSPData.GetSolution(solutions[i], qualities[i])));
     }
 
     public virtual void Load(PTSPData data) {
-      try {
-        SuppressEvents = true;
-        if (data.Coordinates == null && data.Distances == null)
-          throw new System.IO.InvalidDataException("The given instance specifies neither coordinates nor distances!");
-        if (data.Dimension > DistanceMatrixSizeLimit && (data.Coordinates == null || data.Coordinates.GetLength(0) != data.Dimension || data.Coordinates.GetLength(1) != 2))
-          throw new System.IO.InvalidDataException("The given instance is too large for using a distance matrix and there is a problem with the coordinates.");
-        if (data.Coordinates != null && (data.Coordinates.GetLength(0) != data.Dimension || data.Coordinates.GetLength(1) != 2))
-          throw new System.IO.InvalidDataException("The coordinates of the given instance are not in the right format, there need to be one row for each customer and two columns for the x and y coordinates respectively.");
+      if (data.Coordinates == null && data.Distances == null)
+        throw new System.IO.InvalidDataException("The given instance specifies neither coordinates nor distances!");
+      if (data.Dimension > DistanceMatrixSizeLimit && (data.DistanceMeasure == DistanceMeasure.Att
+        || data.DistanceMeasure == DistanceMeasure.Manhattan
+        || data.DistanceMeasure == DistanceMeasure.Maximum))
+        throw new System.IO.InvalidDataException("The given instance uses an unsupported distance measure and is too large for using a distance matrix.");
+      if (data.Coordinates != null && data.Coordinates.GetLength(1) != 2)
+        throw new System.IO.InvalidDataException("The coordinates of the given instance are not in the right format, there need to be one row for each customer and two columns for the x and y coordinates.");
 
+      Encoding.Length = data.Dimension;
+      Name = data.Name;
+      Description = data.Description;
+
+      if (data.Dimension <= DistanceMatrixSizeLimit) {
+        ProbabilisticTSPData = new MatrixProbabilisticTSPData(data.Name, data.GetDistanceMatrix(), data.Probabilities, data.Coordinates) { Description = data.Description };
+      } else if (data.DistanceMeasure == DistanceMeasure.Direct && data.Distances != null) {
+        ProbabilisticTSPData = new MatrixProbabilisticTSPData(data.Name, data.Distances, data.Probabilities, data.Coordinates) { Description = data.Description };
+      } else {
         switch (data.DistanceMeasure) {
-          case DistanceMeasure.Direct:
-            DistanceCalculator = null;
-            if (data.Dimension > DistanceMatrixSizeLimit && Coordinates != null) {
-              DistanceCalculator = new EuclideanDistance();
-              UseDistanceMatrix = false;
-            } else UseDistanceMatrix = true;
+          case DistanceMeasure.Att:
+            ProbabilisticTSPData = new AttPTSPData(data.Name, data.Coordinates, data.Probabilities) { Description = data.Description };
             break;
-          case DistanceMeasure.Att: DistanceCalculator = new AttDistance(); break;
-          case DistanceMeasure.Euclidean: DistanceCalculator = new EuclideanDistance(); break;
-          case DistanceMeasure.Geo: DistanceCalculator = new GeoDistance(); break;
-          case DistanceMeasure.Manhattan: DistanceCalculator = new ManhattanDistance(); break;
-          case DistanceMeasure.Maximum: DistanceCalculator = new MaximumDistance(); break;
-          case DistanceMeasure.RoundedEuclidean: DistanceCalculator = new RoundedEuclideanDistance(); break;
-          case DistanceMeasure.UpperEuclidean: DistanceCalculator = new UpperEuclideanDistance(); break;
-          default: throw new ArgumentException("Distance measure is unknown");
+          case DistanceMeasure.Euclidean:
+            ProbabilisticTSPData = new EuclideanPTSPData(data.Name, data.Coordinates, data.Probabilities, EuclideanTSPData.DistanceRounding.None) { Description = data.Description };
+            break;
+          case DistanceMeasure.RoundedEuclidean:
+            ProbabilisticTSPData = new EuclideanPTSPData(data.Name, data.Coordinates, data.Probabilities, EuclideanTSPData.DistanceRounding.Midpoint) { Description = data.Description };
+            break;
+          case DistanceMeasure.UpperEuclidean:
+            ProbabilisticTSPData = new EuclideanPTSPData(data.Name, data.Coordinates, data.Probabilities, EuclideanTSPData.DistanceRounding.Ceiling) { Description = data.Description };
+            break;
+          case DistanceMeasure.Geo:
+            ProbabilisticTSPData = new GeoPTSPData(data.Name, data.Coordinates, data.Probabilities) { Description = data.Description };
+            break;
+          case DistanceMeasure.Manhattan:
+            ProbabilisticTSPData = new ManhattanPTSPData(data.Name, data.Coordinates, data.Probabilities) { Description = data.Description };
+            break;
+          case DistanceMeasure.Maximum:
+            ProbabilisticTSPData = new MaximumPTSPData(data.Name, data.Coordinates, data.Probabilities) { Description = data.Description };
+            break;
+          default:
+            throw new System.IO.InvalidDataException("An unknown distance measure is given in the instance!");
         }
+      }
+      BestKnownSolution = null;
+      BestKnownQuality = double.NaN;
 
-        Name = data.Name;
-        Description = data.Description;
-
-        Probabilities = new DoubleArray(data.Probabilities);
-        BestKnownSolution = data.BestKnownTour != null ? new Permutation(PermutationTypes.RelativeUndirected, data.BestKnownTour) : null;
-        Coordinates = data.Coordinates != null && data.Coordinates.GetLength(0) > 0 ? new DoubleMatrix(data.Coordinates) : null;
-        DistanceMatrix = data.Dimension <= DistanceMatrixSizeLimit && UseDistanceMatrix ? new DistanceMatrix(data.GetDistanceMatrix()) : null;
-
-        Encoding.Length = data.Dimension;
-      } finally { SuppressEvents = false; }
+      if (data.BestKnownTour != null) {
+        try {
+          var tour = new Permutation(PermutationTypes.RelativeUndirected, data.BestKnownTour);
+          var tourLength = Evaluate(tour, new FastRandom(1));
+          BestKnownSolution = new TSPSolution(data.Coordinates != null ? new DoubleMatrix(data.Coordinates) : null, tour, new DoubleValue(tourLength));
+          BestKnownQuality = tourLength;
+        } catch (InvalidOperationException) {
+          if (data.BestKnownQuality.HasValue)
+            BestKnownQuality = data.BestKnownQuality.Value;
+        }
+      } else if (data.BestKnownQuality.HasValue) {
+        BestKnownQuality = data.BestKnownQuality.Value;
+      }
       OnReset();
-    }
-
-    private void UpdateInstance() {
-      var len = GetProblemDimension();
-      if (Coordinates != null && Coordinates.Rows <= DistanceMatrixSizeLimit
-        && DistanceCalculator != null && UseDistanceMatrix)
-        DistanceMatrix = new DistanceMatrix(CalculateDistances());
-      if (!UseDistanceMatrix) DistanceMatrix = null;
-      Encoding.Length = len;
-
-      OnReset();
-    }
-
-    private int GetProblemDimension() {
-      if (Coordinates == null && DistanceMatrix == null) throw new InvalidOperationException("Both coordinates and distance matrix are null, please specify at least one of them.");
-      return Coordinates != null ? Coordinates.Rows : DistanceMatrix.Rows;
-    }
-
-    private void Parameterize() {
-      foreach (var similarityCalculator in Operators.OfType<ISolutionSimilarityCalculator>()) {
-        similarityCalculator.SolutionVariableName = Encoding.SolutionCreator.PermutationParameter.ActualName;
-        similarityCalculator.QualityVariableName = Evaluator.QualityParameter.ActualName;
-      }
     }
   }
Index: /branches/2521_ProblemRefactoring/HeuristicLab.Problems.PTSP/3.3/PTSPData.cs
===================================================================
--- /branches/2521_ProblemRefactoring/HeuristicLab.Problems.PTSP/3.3/PTSPData.cs	(revision 17253)
+++ /branches/2521_ProblemRefactoring/HeuristicLab.Problems.PTSP/3.3/PTSPData.cs	(revision 17253)
@@ -0,0 +1,341 @@
+﻿#region License Information
+/* HeuristicLab
+ * Copyright (C) Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ *
+ * This file is part of HeuristicLab.
+ *
+ * HeuristicLab is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * HeuristicLab is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
+ */
+#endregion
+
+using System;
+using HEAL.Attic;
+using HeuristicLab.Common;
+using HeuristicLab.Core;
+using HeuristicLab.Data;
+using HeuristicLab.Problems.Instances;
+using HeuristicLab.Problems.TravelingSalesman;
+
+namespace HeuristicLab.Problems.PTSP {
+  [StorableType("dd2d0ecc-372e-46f1-846f-fb4ca2afa124")]
+  public interface IProbabilisticTSPData : ITSPData {
+    double GetProbability(int city);
+    new PTSPData Export();
+  }
+
+  [Item("Matrix-based p-TSP Data", "p-TSP that is representd by a distance matrix.")]
+  [StorableType("30ebade1-d28c-4e45-b195-c7fa32a15df5")]
+  public class MatrixProbabilisticTSPData : MatrixTSPData, IProbabilisticTSPData {
+    [Storable] public PercentArray Probabilities { get; protected set; }
+
+    [StorableConstructor]
+    protected MatrixProbabilisticTSPData(StorableConstructorFlag _) : base(_) { }
+    protected MatrixProbabilisticTSPData(MatrixProbabilisticTSPData original, Cloner cloner) : base(original, cloner) {
+      Probabilities = original.Probabilities;
+    }
+    public MatrixProbabilisticTSPData() {
+      Name = PTSPDefaultInstance.Name;
+      Matrix = PTSPDefaultInstance.Distances;
+      Probabilities = PTSPDefaultInstance.Probabilities;
+      DisplayCoordinates = PTSPDefaultInstance.Coordinates;
+    }
+    public MatrixProbabilisticTSPData(string name, double[,] matrix, double[] probabilities, double[,] coordinates = null)
+      : base(name, matrix, coordinates) {
+      Probabilities = new PercentArray(probabilities, @readonly: true);
+    }
+    public MatrixProbabilisticTSPData(string name, DoubleMatrix matrix, PercentArray probabilities, DoubleMatrix coordinates = null)
+      : base(name, matrix, coordinates) {
+      Probabilities = probabilities.AsReadOnly();
+    }
+
+    public override IDeepCloneable Clone(Cloner cloner) {
+      return new MatrixProbabilisticTSPData(this, cloner);
+    }
+
+    public double GetProbability(int city) => Probabilities[city];
+
+    public new PTSPData Export() {
+      return new PTSPData() {
+        Name = name,
+        Description = description,
+        Coordinates = DisplayCoordinates?.CloneAsMatrix(),
+        Dimension = Matrix.Rows,
+        DistanceMeasure = DistanceMeasure.Direct,
+        Distances = Matrix.CloneAsMatrix(),
+        Probabilities = Probabilities.CloneAsArray()
+      };
+    }
+  }
+
+  [Item("Euclidean p-TSP Data", "p-TSP that is represented by coordinates in an Euclidean plane.")]
+  [StorableType("8d4cf257-9013-4746-bc6c-37615954c3fb")]
+  public class EuclideanPTSPData : EuclideanTSPData, IProbabilisticTSPData {
+    [Storable] public PercentArray Probabilities { get; protected set; }
+
+    [StorableConstructor]
+    protected EuclideanPTSPData(StorableConstructorFlag _) : base(_) { }
+    protected EuclideanPTSPData(EuclideanPTSPData original, Cloner cloner) : base(original, cloner) {
+      Probabilities = original.Probabilities;
+    }
+    public EuclideanPTSPData() : base() {
+      Name = PTSPDefaultInstance.Name;
+      Coordinates = PTSPDefaultInstance.Coordinates;
+      Probabilities = PTSPDefaultInstance.Probabilities;
+      Rounding = DistanceRounding.Midpoint;
+    }
+    public EuclideanPTSPData(string name, double[,] coordinates, double[] probabilities, DistanceRounding rounding = DistanceRounding.None)
+      : base(name, coordinates) {
+      if (coordinates.GetLength(0) != probabilities.Length) throw new InvalidOperationException("Number of cities is ambiguous between " + nameof(coordinates) + " and " + nameof(probabilities) + ".");
+      Probabilities = new PercentArray(probabilities, @readonly: true);
+    }
+    public EuclideanPTSPData(string name, DoubleMatrix coordinates, PercentArray probabilities, DistanceRounding rounding = DistanceRounding.None)
+      : base(name, coordinates, rounding) {
+      if (coordinates.Rows != probabilities.Length) throw new InvalidOperationException("Number of cities is ambiguous between " + nameof(coordinates) + " and " + nameof(probabilities) + ".");
+      Probabilities = probabilities.AsReadOnly();
+    }
+
+    public override IDeepCloneable Clone(Cloner cloner) {
+      return new EuclideanPTSPData(this, cloner);
+    }
+
+    public double GetProbability(int city) => Probabilities[city];
+
+    public new PTSPData Export() {
+      var data = new PTSPData() {
+        Name = name,
+        Description = description,
+        Coordinates = Coordinates.CloneAsMatrix(),
+        Probabilities = Probabilities.CloneAsArray(),
+        Dimension = Coordinates.Rows,
+      };
+      switch (Rounding) {
+        case DistanceRounding.None: data.DistanceMeasure = DistanceMeasure.Euclidean; break;
+        case DistanceRounding.Midpoint: data.DistanceMeasure = DistanceMeasure.RoundedEuclidean; break;
+        case DistanceRounding.Ceiling: data.DistanceMeasure = DistanceMeasure.UpperEuclidean; break;
+      }
+      return data;
+    }
+  }
+
+  [Item("Geo p-TSP Data", "p-TSP that is represented by geo coordinates.")]
+  [StorableType("b175e0be-5706-4c44-b3f0-dcb948d5c47a")]
+  public class GeoPTSPData : GeoTSPData, IProbabilisticTSPData {
+    [Storable] public PercentArray Probabilities { get; protected set; }
+
+    [StorableConstructor]
+    protected GeoPTSPData(StorableConstructorFlag _) : base(_) { }
+    protected GeoPTSPData(GeoPTSPData original, Cloner cloner)
+      : base(original, cloner) {
+      Probabilities = original.Probabilities;
+    }
+    public GeoPTSPData() : base() {
+      Name = PTSPDefaultInstance.Name;
+      Coordinates = PTSPDefaultInstance.Coordinates;
+      Probabilities = PTSPDefaultInstance.Probabilities;
+    }
+    public GeoPTSPData(string name, double[,] coordinates, double[] probabilities)
+      : base(name, coordinates) {
+      if (coordinates.GetLength(0) != probabilities.Length) throw new InvalidOperationException("Number of cities is ambiguous between " + nameof(coordinates) + " and " + nameof(probabilities) + ".");
+      Probabilities = new PercentArray(probabilities, @readonly: true);
+    }
+    public GeoPTSPData(string name, DoubleMatrix coordinates, PercentArray probabilities)
+      : base(name, coordinates) {
+      if (coordinates.Rows != probabilities.Length) throw new InvalidOperationException("Number of cities is ambiguous between " + nameof(coordinates) + " and " + nameof(probabilities) + ".");
+      Probabilities = probabilities.AsReadOnly();
+    }
+
+    public override IDeepCloneable Clone(Cloner cloner) {
+      return new GeoPTSPData(this, cloner);
+    }
+
+    public double GetProbability(int city) => Probabilities[city];
+
+    public new PTSPData Export() {
+      return new PTSPData() {
+        Name = name,
+        Description = description,
+        Coordinates = Coordinates.CloneAsMatrix(),
+        Probabilities = Probabilities.CloneAsArray(),
+        Dimension = Coordinates.Rows,
+        DistanceMeasure = DistanceMeasure.Geo,
+      };
+    }
+  }
+
+  [Item("ATT p-TSP Data", "p-TSP that is represented by ATT distance.")]
+  [StorableType("7a2aa605-58d2-4533-a763-3d474e185460")]
+  public class AttPTSPData : AttTSPData, IProbabilisticTSPData {
+    [Storable] public PercentArray Probabilities { get; protected set; }
+
+    [StorableConstructor]
+    protected AttPTSPData(StorableConstructorFlag _) : base(_) { }
+    protected AttPTSPData(AttPTSPData original, Cloner cloner)
+      : base(original, cloner) {
+      Probabilities = original.Probabilities;
+    }
+    public AttPTSPData() : base() {
+      Name = PTSPDefaultInstance.Name;
+      Coordinates = PTSPDefaultInstance.Coordinates;
+      Probabilities = PTSPDefaultInstance.Probabilities;
+    }
+    public AttPTSPData(string name, double[,] coordinates, double[] probabilities)
+      : base(name, coordinates) {
+      if (coordinates.GetLength(0) != probabilities.Length) throw new InvalidOperationException("Number of cities is ambiguous between " + nameof(coordinates) + " and " + nameof(probabilities) + ".");
+      Probabilities = new PercentArray(probabilities, @readonly: true);
+    }
+    public AttPTSPData(string name, DoubleMatrix coordinates, PercentArray probabilities)
+      : base(name, coordinates) {
+      if (coordinates.Rows != probabilities.Length) throw new InvalidOperationException("Number of cities is ambiguous between " + nameof(coordinates) + " and " + nameof(probabilities) + ".");
+      Probabilities = probabilities.AsReadOnly();
+    }
+
+    public override IDeepCloneable Clone(Cloner cloner) {
+      return new AttPTSPData(this, cloner);
+    }
+
+    public double GetProbability(int city) => Probabilities[city];
+
+    public new PTSPData Export() {
+      return new PTSPData() {
+        Name = name,
+        Description = description,
+        Coordinates = Coordinates.CloneAsMatrix(),
+        Probabilities = Probabilities.CloneAsArray(),
+        Dimension = Coordinates.Rows,
+        DistanceMeasure = DistanceMeasure.Att,
+      };
+    }
+  }
+
+  [Item("Manhattan p-TSP Data", "p-TSP that is represented by Manhattan distance.")]
+  [StorableType("cc43d1db-3da9-4d6e-becb-6b475b42fc59")]
+  public class ManhattanPTSPData : ManhattanTSPData, IProbabilisticTSPData {
+    [Storable] public PercentArray Probabilities { get; protected set; }
+
+    [StorableConstructor]
+    protected ManhattanPTSPData(StorableConstructorFlag _) : base(_) { }
+    protected ManhattanPTSPData(ManhattanPTSPData original, Cloner cloner)
+      : base(original, cloner) {
+      Probabilities = original.Probabilities;
+    }
+    public ManhattanPTSPData() : base() {
+      Name = PTSPDefaultInstance.Name;
+      Coordinates = PTSPDefaultInstance.Coordinates;
+      Probabilities = PTSPDefaultInstance.Probabilities;
+    }
+    public ManhattanPTSPData(string name, double[,] coordinates, double[] probabilities)
+      : base(name, coordinates) {
+      if (coordinates.GetLength(0) != probabilities.Length) throw new InvalidOperationException("Number of cities is ambiguous between " + nameof(coordinates) + " and " + nameof(probabilities) + ".");
+      Probabilities = new PercentArray(probabilities, @readonly: true);
+    }
+    public ManhattanPTSPData(string name, DoubleMatrix coordinates, PercentArray probabilities)
+      : base(name, coordinates) {
+      if (coordinates.Rows != probabilities.Length) throw new InvalidOperationException("Number of cities is ambiguous between " + nameof(coordinates) + " and " + nameof(probabilities) + ".");
+      Probabilities = probabilities.AsReadOnly();
+    }
+
+    public override IDeepCloneable Clone(Cloner cloner) {
+      return new ManhattanPTSPData(this, cloner);
+    }
+
+    public double GetProbability(int city) => Probabilities[city];
+
+    public new PTSPData Export() {
+      return new PTSPData() {
+        Name = name,
+        Description = description,
+        Coordinates = Coordinates.CloneAsMatrix(),
+        Probabilities = Probabilities.CloneAsArray(),
+        Dimension = Coordinates.Rows,
+        DistanceMeasure = DistanceMeasure.Manhattan,
+      };
+    }
+  }
+
+  [Item("Maximum p-TSP Data", "p-TSP that is represented by maximum absolute distance in either the x or y coordinates.")]
+  [StorableType("82e9cde2-a942-403a-80ff-8deae4fa8214")]
+  public class MaximumPTSPData : MaximumTSPData, IProbabilisticTSPData {
+    [Storable] public PercentArray Probabilities { get; protected set; }
+
+    [StorableConstructor]
+    protected MaximumPTSPData(StorableConstructorFlag _) : base(_) { }
+    protected MaximumPTSPData(MaximumPTSPData original, Cloner cloner)
+      : base(original, cloner) {
+      Probabilities = original.Probabilities;
+    }
+    public MaximumPTSPData() : base() {
+      Name = PTSPDefaultInstance.Name;
+      Coordinates = PTSPDefaultInstance.Coordinates;
+      Probabilities = PTSPDefaultInstance.Probabilities;
+    }
+    public MaximumPTSPData(string name, double[,] coordinates, double[] probabilities)
+      : base(name, coordinates) {
+      if (coordinates.GetLength(0) != probabilities.Length) throw new InvalidOperationException("Number of cities is ambiguous between " + nameof(coordinates) + " and " + nameof(probabilities) + ".");
+      Probabilities = new PercentArray(probabilities, @readonly: true);
+    }
+    public MaximumPTSPData(string name, DoubleMatrix coordinates, PercentArray probabilities)
+      : base(name, coordinates) {
+      if (coordinates.Rows != probabilities.Length) throw new InvalidOperationException("Number of cities is ambiguous between " + nameof(coordinates) + " and " + nameof(probabilities) + ".");
+      Probabilities = probabilities.AsReadOnly();
+    }
+
+    public override IDeepCloneable Clone(Cloner cloner) {
+      return new MaximumPTSPData(this, cloner);
+    }
+
+    public double GetProbability(int city) => Probabilities[city];
+
+    public new PTSPData Export() {
+      return new PTSPData() {
+        Name = name,
+        Description = description,
+        Coordinates = Coordinates.CloneAsMatrix(),
+        Probabilities = Probabilities.CloneAsArray(),
+        Dimension = Coordinates.Rows,
+        DistanceMeasure = DistanceMeasure.Maximum,
+      };
+    }
+  }
+
+  internal static class PTSPDefaultInstance {
+    internal static readonly DoubleMatrix Distances = new DoubleMatrix(new double[,] {
+{ 0, 100, 200, 300, 100, 141, 224, 316, 200, 224, 283, 361, 300, 316, 361, 424 },
+{ 100, 0, 100, 200, 141, 100, 141, 224, 224, 200, 224, 283, 316, 300, 316, 361 },
+{ 200, 100, 0, 100, 224, 141, 100, 141, 283, 224, 200, 224, 361, 316, 300, 316 },
+{ 300, 200, 100, 0, 316, 224, 141, 100, 361, 283, 224, 200, 424, 361, 316, 300 },
+{ 100, 141, 224, 316, 0, 100, 200, 300, 100, 141, 224, 316, 200, 224, 283, 361 },
+{ 141, 100, 141, 224, 100, 0, 100, 200, 141, 100, 141, 224, 224, 200, 224, 283 },
+{ 224, 141, 100, 141, 200, 100, 0, 100, 224, 141, 100, 141, 283, 224, 200, 224 },
+{ 316, 224, 141, 100, 300, 200, 100, 0, 316, 224, 141, 100, 361, 283, 224, 200 },
+{ 200, 224, 283, 361, 100, 141, 224, 316, 0, 100, 200, 300, 100, 141, 224, 316 },
+{ 224, 200, 224, 283, 141, 100, 141, 224, 100, 0, 100, 200, 141, 100, 141, 224 },
+{ 283, 224, 200, 224, 224, 141, 100, 141, 200, 100, 0, 100, 224, 141, 100, 141 },
+{ 361, 283, 224, 200, 316, 224, 141, 100, 300, 200, 100, 0, 316, 224, 141, 100 },
+{ 300, 316, 361, 424, 200, 224, 283, 361, 100, 141, 224, 316, 0, 100, 200, 300 },
+{ 316, 300, 316, 361, 224, 200, 224, 283, 141, 100, 141, 224, 100, 0, 100, 200 },
+{ 361, 316, 300, 316, 283, 224, 200, 224, 224, 141, 100, 141, 200, 100, 0, 100 },
+{ 424, 361, 316, 300, 361, 283, 224, 200, 316, 224, 141, 100, 300, 200, 100, 0 },
+}, @readonly: true);
+    internal static readonly DoubleMatrix Coordinates = new DoubleMatrix(new double[,] {
+{ 100, 100 }, { 100, 200 }, { 100, 300 }, { 100, 400 },
+{ 200, 100 }, { 200, 200 }, { 200, 300 }, { 200, 400 },
+{ 300, 100 }, { 300, 200 }, { 300, 300 }, { 300, 400 },
+{ 400, 100 }, { 400, 200 }, { 400, 300 }, { 400, 400 }
+}, @readonly: true);
+    internal static readonly PercentArray Probabilities = new PercentArray(new double[] {
+0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8, 0.7, 0.6, 0.5, 0.4, 0.3, 0.2, 0.3, 0.4, 0.5
+}, @readonly: true);
+    internal static readonly string Name = "HL PTSP Default";
+  }
+}
Index: anches/2521_ProblemRefactoring/HeuristicLab.Problems.PTSP/3.3/PathPTSPTour.cs
===================================================================
--- /branches/2521_ProblemRefactoring/HeuristicLab.Problems.PTSP/3.3/PathPTSPTour.cs	(revision 17252)
+++ 	(revision )
@@ -1,223 +1,0 @@
-﻿#region License Information
-/* HeuristicLab
- * Copyright (C) Heuristic and Evolutionary Algorithms Laboratory (HEAL)
- *
- * This file is part of HeuristicLab.
- *
- * HeuristicLab is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * HeuristicLab is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
- */
-#endregion
-
-using System;
-using System.Drawing;
-using HeuristicLab.Common;
-using HeuristicLab.Core;
-using HeuristicLab.Data;
-using HeuristicLab.Encodings.PermutationEncoding;
-using HEAL.Attic;
-
-namespace HeuristicLab.Problems.PTSP {
-  /// <summary>
-  /// Represents a tour of a Probabilistic Traveling Salesman Problem given in path representation which can be visualized in the GUI.
-  /// </summary>
-  [Item("PathPTSPTour", "Represents a tour of a Probabilistic Traveling Salesman Problem given in path representation which can be visualized in the GUI.")]
-  [StorableType("8C9E50C9-4364-48F1-B681-9CFFD1147EF0")]
-  public sealed class PathPTSPTour : Item {
-    public static new Image StaticItemImage {
-      get { return HeuristicLab.Common.Resources.VSImageLibrary.Image; }
-    }
-
-    [Storable]
-    private DoubleMatrix coordinates;
-    public DoubleMatrix Coordinates {
-      get { return coordinates; }
-      set {
-        if (coordinates != value) {
-          if (coordinates != null) DeregisterCoordinatesEvents();
-          coordinates = value;
-          if (coordinates != null) RegisterCoordinatesEvents();
-          OnCoordinatesChanged();
-        }
-      }
-    }
-    [Storable]
-    private Permutation permutation;
-    public Permutation Permutation {
-      get { return permutation; }
-      set {
-        if (permutation != value) {
-          if (permutation != null) DeregisterPermutationEvents();
-          permutation = value;
-          if (permutation != null) RegisterPermutationEvents();
-          OnPermutationChanged();
-        }
-      }
-    }
-    [Storable]
-    private DoubleValue quality;
-    public DoubleValue Quality {
-      get { return quality; }
-      set {
-        if (quality != value) {
-          if (quality != null) DeregisterQualityEvents();
-          quality = value;
-          if (quality != null) RegisterQualityEvents();
-          OnQualityChanged();
-        }
-      }
-    }
-    [Storable]
-    private DoubleArray probabilities;
-    public DoubleArray Probabilities {
-      get { return probabilities; }
-      set {
-        if (probabilities != value) {
-          if (probabilities != null) DeregisterProbabilitiesEvents();
-          probabilities = value;
-          if (probabilities != null) RegisterProbabilitiesEvents();
-          OnQualityChanged();
-        }
-      }
-    }
-
-    [StorableConstructor]
-    private PathPTSPTour(StorableConstructorFlag _) : base(_) { }
-    private PathPTSPTour(PathPTSPTour original, Cloner cloner)
-      : base(original, cloner) {
-      this.coordinates = cloner.Clone(original.coordinates);
-      this.probabilities = cloner.Clone(original.probabilities);
-      this.permutation = cloner.Clone(original.permutation);
-      this.quality = cloner.Clone(original.quality);
-      Initialize();
-    }
-    public PathPTSPTour() : base() { }
-    public PathPTSPTour(DoubleMatrix coordinates, DoubleArray probabilities)
-      : base() {
-      this.coordinates = coordinates;
-      this.probabilities = probabilities;
-      Initialize();
-    }
-    public PathPTSPTour(DoubleMatrix coordinates, DoubleArray probabilities, Permutation permutation)
-      : base() {
-      this.coordinates = coordinates;
-      this.probabilities = probabilities;
-      this.permutation = permutation;
-      Initialize();
-    }
-    public PathPTSPTour(DoubleMatrix coordinates, DoubleArray probabilities, Permutation permutation, DoubleValue quality)
-      : base() {
-      this.coordinates = coordinates;
-      this.probabilities = probabilities;
-      this.permutation = permutation;
-      this.quality = quality;
-      Initialize();
-    }
-
-    public override IDeepCloneable Clone(Cloner cloner) {
-      return new PathPTSPTour(this, cloner);
-    }
-
-    [StorableHook(HookType.AfterDeserialization)]
-    private void AfterDeserialization() {
-      Initialize();
-    }
-
-    private void Initialize() {
-      if (coordinates != null) RegisterCoordinatesEvents();
-      if (probabilities != null) RegisterProbabilitiesEvents();
-      if (permutation != null) RegisterPermutationEvents();
-      if (quality != null) RegisterQualityEvents();
-    }
-
-    #region Events
-    public event EventHandler CoordinatesChanged;
-    private void OnCoordinatesChanged() {
-      var changed = CoordinatesChanged;
-      if (changed != null)
-        changed(this, EventArgs.Empty);
-    }
-    public event EventHandler ProbabilitiesChanged;
-    private void OnProbabilitiesChanged() {
-      var changed = ProbabilitiesChanged;
-      if (changed != null)
-        changed(this, EventArgs.Empty);
-    }
-    public event EventHandler PermutationChanged;
-    private void OnPermutationChanged() {
-      var changed = PermutationChanged;
-      if (changed != null)
-        changed(this, EventArgs.Empty);
-    }
-    public event EventHandler QualityChanged;
-    private void OnQualityChanged() {
-      var changed = QualityChanged;
-      if (changed != null)
-        changed(this, EventArgs.Empty);
-    }
-
-    private void RegisterCoordinatesEvents() {
-      Coordinates.ItemChanged += new EventHandler<EventArgs<int, int>>(Coordinates_ItemChanged);
-      Coordinates.Reset += new EventHandler(Coordinates_Reset);
-    }
-    private void DeregisterCoordinatesEvents() {
-      Coordinates.ItemChanged -= new EventHandler<EventArgs<int, int>>(Coordinates_ItemChanged);
-      Coordinates.Reset -= new EventHandler(Coordinates_Reset);
-    }
-    private void RegisterProbabilitiesEvents() {
-      Probabilities.ItemChanged += new EventHandler<EventArgs<int>>(Probabilities_ItemChanged);
-      Probabilities.Reset += new EventHandler(Probabilities_Reset);
-    }
-    private void DeregisterProbabilitiesEvents() {
-      Probabilities.ItemChanged -= new EventHandler<EventArgs<int>>(Probabilities_ItemChanged);
-      Probabilities.Reset -= new EventHandler(Probabilities_Reset);
-    }
-    private void RegisterPermutationEvents() {
-      Permutation.ItemChanged += new EventHandler<EventArgs<int>>(Permutation_ItemChanged);
-      Permutation.Reset += new EventHandler(Permutation_Reset);
-    }
-    private void DeregisterPermutationEvents() {
-      Permutation.ItemChanged -= new EventHandler<EventArgs<int>>(Permutation_ItemChanged);
-      Permutation.Reset -= new EventHandler(Permutation_Reset);
-    }
-    private void RegisterQualityEvents() {
-      Quality.ValueChanged += new EventHandler(Quality_ValueChanged);
-    }
-    private void DeregisterQualityEvents() {
-      Quality.ValueChanged -= new EventHandler(Quality_ValueChanged);
-    }
-
-    private void Coordinates_ItemChanged(object sender, EventArgs<int, int> e) {
-      OnCoordinatesChanged();
-    }
-    private void Coordinates_Reset(object sender, EventArgs e) {
-      OnCoordinatesChanged();
-    }
-    private void Probabilities_ItemChanged(object sender, EventArgs<int> e) {
-      OnProbabilitiesChanged();
-    }
-    private void Probabilities_Reset(object sender, EventArgs e) {
-      OnProbabilitiesChanged();
-    }
-    private void Permutation_ItemChanged(object sender, EventArgs<int> e) {
-      OnPermutationChanged();
-    }
-    private void Permutation_Reset(object sender, EventArgs e) {
-      OnPermutationChanged();
-    }
-    private void Quality_ValueChanged(object sender, EventArgs e) {
-      OnQualityChanged();
-    }
-    #endregion
-  }
-}
Index: /branches/2521_ProblemRefactoring/HeuristicLab.Problems.PTSP/3.3/Plugin.cs.frame
===================================================================
--- /branches/2521_ProblemRefactoring/HeuristicLab.Problems.PTSP/3.3/Plugin.cs.frame	(revision 17252)
+++ /branches/2521_ProblemRefactoring/HeuristicLab.Problems.PTSP/3.3/Plugin.cs.frame	(revision 17253)
@@ -38,4 +38,5 @@
   [PluginDependency("HeuristicLab.Attic", "1.0")]
   [PluginDependency("HeuristicLab.Problems.Instances", "3.3")]
+  [PluginDependency("HeuristicLab.Problems.TravelingSalesman", "3.3")]
   [PluginDependency("HeuristicLab.Random", "3.3")]
   public class HeuristicLabProblemsPTSPPlugin : PluginBase {
Index: /branches/2521_ProblemRefactoring/HeuristicLab.Problems.QuadraticAssignment/3.3/QuadraticAssignmentProblem.cs
===================================================================
--- /branches/2521_ProblemRefactoring/HeuristicLab.Problems.QuadraticAssignment/3.3/QuadraticAssignmentProblem.cs	(revision 17252)
+++ /branches/2521_ProblemRefactoring/HeuristicLab.Problems.QuadraticAssignment/3.3/QuadraticAssignmentProblem.cs	(revision 17253)
@@ -177,4 +177,5 @@
     protected override void OnEncodingChanged() {
       base.OnEncodingChanged();
+      Encoding.Length = Weights.Rows;
       Parameterize();
     }
Index: /branches/2521_ProblemRefactoring/HeuristicLab.Problems.TravelingSalesman/3.3/TSP.cs
===================================================================
--- /branches/2521_ProblemRefactoring/HeuristicLab.Problems.TravelingSalesman/3.3/TSP.cs	(revision 17252)
+++ /branches/2521_ProblemRefactoring/HeuristicLab.Problems.TravelingSalesman/3.3/TSP.cs	(revision 17253)
@@ -72,7 +72,10 @@
 
       TSPData = new EuclideanTSPData();
+      Encoding.Length = TSPData.Cities;
 
       InitializeOperators();
     }
+
+    // TODO: encoding length should not be changeable
 
     public override IDeepCloneable Clone(Cloner cloner) {
@@ -99,13 +102,21 @@
         i = qualities.Select((x, index) => new { index, Fitness = x }).OrderBy(x => x.Fitness).First().index;
       else i = qualities.Select((x, index) => new { index, Fitness = x }).OrderByDescending(x => x.Fitness).First().index;
-      var solution = TSPData.GetSolution(solutions[i], qualities[i]);
 
       if (double.IsNaN(BestKnownQuality) ||
           Maximization && qualities[i] > BestKnownQuality ||
           !Maximization && qualities[i] < BestKnownQuality) {
+        var bestKnown = TSPData.GetSolution(solutions[i], qualities[i]);
         BestKnownQualityParameter.Value = new DoubleValue(qualities[i]);
-        BestKnownSolutionParameter.Value = solution;
-      }
-      results.AddOrUpdateResult("Best TSP Solution", solution);
+        BestKnownSolutionParameter.Value = bestKnown;
+      }
+
+      IResult bestSolutionResult;
+      if (results.TryGetValue("Best TSP Solution", out bestSolutionResult)) {
+        var bestSolution = bestSolutionResult.Value as ITSPSolution;
+        if (bestSolution == null || Maximization && bestSolution.TourLength.Value < qualities[i]
+          || !Maximization && bestSolution.TourLength.Value > qualities[i]) {
+          bestSolutionResult.Value = TSPData.GetSolution(solutions[i], qualities[i]);
+        }
+      } else results.Add(new Result("Best TSP Solution", TSPData.GetSolution(solutions[i], qualities[i])));
     }
 
@@ -132,8 +143,5 @@
       Description = data.Description;
 
-      if (data.DistanceMeasure == DistanceMeasure.Att
-        || data.DistanceMeasure == DistanceMeasure.Manhattan
-        || data.DistanceMeasure == DistanceMeasure.Maximum
-        || data.Dimension <= DistanceMatrixSizeLimit) {
+      if (data.Dimension <= DistanceMatrixSizeLimit) {
         TSPData = new MatrixTSPData(data.Name, data.GetDistanceMatrix(), data.Coordinates) { Description = data.Description };
       } else if (data.DistanceMeasure == DistanceMeasure.Direct && data.Distances != null) {
@@ -141,4 +149,7 @@
       } else {
         switch (data.DistanceMeasure) {
+          case DistanceMeasure.Att:
+            TSPData = new AttTSPData(data.Name, data.Coordinates) { Description = data.Description };
+            break;
           case DistanceMeasure.Euclidean:
             TSPData = new EuclideanTSPData(data.Name, data.Coordinates, EuclideanTSPData.DistanceRounding.None) { Description = data.Description };
@@ -152,4 +163,10 @@
           case DistanceMeasure.Geo:
             TSPData = new GeoTSPData(data.Name, data.Coordinates) { Description = data.Description };
+            break;
+          case DistanceMeasure.Manhattan:
+            TSPData = new ManhattanTSPData(data.Name, data.Coordinates) { Description = data.Description };
+            break;
+          case DistanceMeasure.Maximum:
+            TSPData = new MaximumTSPData(data.Name, data.Coordinates) { Description = data.Description };
             break;
           default:
@@ -185,6 +202,8 @@
     }
 
+
     protected override void OnEncodingChanged() {
       base.OnEncodingChanged();
+      Encoding.Length = TSPData.Cities;
       ParameterizeOperators();
     }
Index: /branches/2521_ProblemRefactoring/HeuristicLab.Problems.TravelingSalesman/3.3/TSPData.cs
===================================================================
--- /branches/2521_ProblemRefactoring/HeuristicLab.Problems.TravelingSalesman/3.3/TSPData.cs	(revision 17252)
+++ /branches/2521_ProblemRefactoring/HeuristicLab.Problems.TravelingSalesman/3.3/TSPData.cs	(revision 17253)
@@ -31,4 +31,6 @@
   [StorableType("1a9bf60c-b6a6-4c95-8e99-5a2dec0ee892")]
   public interface ITSPData : INamedItem {
+    int Cities { get; }
+
     double GetDistance(int fromCity, int toCity);
     ITSPSolution GetSolution(Permutation tspTour, double tourLength);
@@ -38,11 +40,13 @@
   [Item("Matrix-based TSP Data", "TSP that is representd by a distance matrix.")]
   [StorableType("4df58a35-679d-4414-b815-9450ae100823")]
-  public sealed class MatrixTSPData : NamedItem, ITSPData {
-    [Storable] public DoubleMatrix Matrix { get; private set; }
-    [Storable] public DoubleMatrix DisplayCoordinates { get; private set; }
-
-    [StorableConstructor]
-    private MatrixTSPData(StorableConstructorFlag _) : base(_) { }
-    private MatrixTSPData(MatrixTSPData original, Cloner cloner) : base(original, cloner) {
+  public class MatrixTSPData : NamedItem, ITSPData {
+    [Storable] public DoubleMatrix Matrix { get; protected set; }
+    [Storable] public DoubleMatrix DisplayCoordinates { get; protected set; }
+
+    public int Cities => Matrix.Rows;
+
+    [StorableConstructor]
+    protected  MatrixTSPData(StorableConstructorFlag _) : base(_) { }
+    protected MatrixTSPData(MatrixTSPData original, Cloner cloner) : base(original, cloner) {
       Matrix = original.Matrix;
       DisplayCoordinates = original.DisplayCoordinates;
@@ -68,9 +72,9 @@
         throw new ArgumentException("Unequal number of rows in " + nameof(matrix) + " and " + nameof(coordinates) + ".");
       Name = name;
-      Matrix = (DoubleMatrix)matrix.AsReadOnly();
-      DisplayCoordinates = (DoubleMatrix)coordinates?.AsReadOnly();
-    }
-
-    public ITSPSolution GetSolution(Permutation tour, double tourLength) {
+      Matrix = matrix.AsReadOnly();
+      DisplayCoordinates = coordinates?.AsReadOnly();
+    }
+
+    public virtual ITSPSolution GetSolution(Permutation tour, double tourLength) {
       return new TSPSolution(DisplayCoordinates, tour, new DoubleValue(tourLength));
     }
@@ -97,5 +101,7 @@
   [StorableType("3955d07a-d43c-4a01-9505-d2effb1ea865")]
   public abstract class CoordinatesTSPData : NamedItem, ITSPData {
-    [Storable] public DoubleMatrix Coordinates { get; private set; }
+    [Storable] public DoubleMatrix Coordinates { get; protected set; }
+
+    public int Cities => Coordinates.Rows;
 
     [StorableConstructor]
@@ -118,5 +124,5 @@
       if (coordinates.Columns != 2) throw new ArgumentException("Argument must have exactly two columns.", nameof(coordinates));
       Name = name;
-      Coordinates = (DoubleMatrix)coordinates.AsReadOnly();
+      Coordinates = coordinates.AsReadOnly();
     }
 
@@ -128,5 +134,5 @@
     public abstract double GetDistance(double fromX, double fromY, double toX, double toY);
 
-    public ITSPSolution GetSolution(Permutation tour, double tourLength) {
+    public virtual ITSPSolution GetSolution(Permutation tour, double tourLength) {
       return new TSPSolution(Coordinates, tour, new DoubleValue(tourLength));
     }
@@ -137,13 +143,13 @@
   [Item("Euclidean TSP Data", "TSP that is represented by coordinates in an Euclidean plane.")]
   [StorableType("4bf58348-cd98-46c5-a4c0-55f486ca88b4")]
-  public sealed class EuclideanTSPData : CoordinatesTSPData {
+  public class EuclideanTSPData : CoordinatesTSPData {
     public enum DistanceRounding { None, Midpoint, Ceiling }
 
     [Storable]
-    public DistanceRounding Rounding { get; private set; }
-
-    [StorableConstructor]
-    private EuclideanTSPData(StorableConstructorFlag _) : base(_) { }
-    private EuclideanTSPData(EuclideanTSPData original, Cloner cloner) : base(original, cloner) {
+    public DistanceRounding Rounding { get; protected set; }
+
+    [StorableConstructor]
+    protected EuclideanTSPData(StorableConstructorFlag _) : base(_) { }
+    protected EuclideanTSPData(EuclideanTSPData original, Cloner cloner) : base(original, cloner) {
       Rounding = original.Rounding;
     }
@@ -166,5 +172,5 @@
 
     public override double GetDistance(double fromX, double fromY, double toX, double toY) {
-      var dist = Math.Sqrt((fromX - toX) * (fromX - toX) + (fromY - toY) * (fromY - toY));
+      var dist = DistanceHelper.EuclideanDistance(fromX, fromY, toX, toY);
       switch (Rounding) {
         case DistanceRounding.None: return dist;
@@ -193,11 +199,8 @@
   [Item("Geo TSP Data", "TSP that is represented by geo coordinates.")]
   [StorableType("4bf58348-cd98-46c5-a4c0-55f486ca88b4")]
-  public sealed class GeoTSPData : CoordinatesTSPData {
-    public const double PI = 3.141592;
-    public const double RADIUS = 6378.388;
-
-    [StorableConstructor]
-    private GeoTSPData(StorableConstructorFlag _) : base(_) { }
-    private GeoTSPData(GeoTSPData original, Cloner cloner) : base(original, cloner) { }
+  public class GeoTSPData : CoordinatesTSPData {
+    [StorableConstructor]
+    protected GeoTSPData(StorableConstructorFlag _) : base(_) { }
+    protected GeoTSPData(GeoTSPData original, Cloner cloner) : base(original, cloner) { }
     public GeoTSPData() : base() { }
     public GeoTSPData(string name, double[,] coordinates) : base(name, coordinates) { }
@@ -209,23 +212,5 @@
 
     public override double GetDistance(double fromX, double fromY, double toX, double toY) {
-      double latitude1, longitude1, latitude2, longitude2;
-      double q1, q2, q3;
-      double length;
-
-      latitude1 = ConvertToRadian(fromX);
-      longitude1 = ConvertToRadian(fromY);
-      latitude2 = ConvertToRadian(toX);
-      longitude2 = ConvertToRadian(toY);
-
-      q1 = Math.Cos(longitude1 - longitude2);
-      q2 = Math.Cos(latitude1 - latitude2);
-      q3 = Math.Cos(latitude1 + latitude2);
-
-      length = (int)(RADIUS * Math.Acos(0.5 * ((1.0 + q1) * q2 - (1.0 - q1) * q3)) + 1.0);
-      return (length);
-    }
-
-    private double ConvertToRadian(double x) {
-      return PI * (Math.Truncate(x) + 5.0 * (x - Math.Truncate(x)) / 3.0) / 180.0;
+      return DistanceHelper.GeoDistance(fromX, fromY, toX, toY);
     }
 
@@ -237,4 +222,91 @@
         Dimension = Coordinates.Rows,
         DistanceMeasure = DistanceMeasure.Geo
+      };
+    }
+  }
+
+  [Item("ATT TSP Data", "TSP that is represented by ATT coordinates.")]
+  [StorableType("d7a0add3-6ec1-42e0-b1d7-b6454694d485")]
+  public class AttTSPData : CoordinatesTSPData {
+    [StorableConstructor]
+    protected AttTSPData(StorableConstructorFlag _) : base(_) { }
+    protected AttTSPData(AttTSPData original, Cloner cloner) : base(original, cloner) { }
+    public AttTSPData() : base() { }
+    public AttTSPData(string name, double[,] coordinates) : base(name, coordinates) { }
+    public AttTSPData(string name, DoubleMatrix coordinates) : base(name, coordinates) { }
+
+    public override IDeepCloneable Clone(Cloner cloner) {
+      return new AttTSPData(this, cloner);
+    }
+
+    public override double GetDistance(double fromX, double fromY, double toX, double toY) {
+      return DistanceHelper.AttDistance(fromX, fromY, toX, toY);
+    }
+
+    public override TSPData Export() {
+      return new TSPData() {
+        Name = name,
+        Description = description,
+        Coordinates = Coordinates.CloneAsMatrix(),
+        Dimension = Coordinates.Rows,
+        DistanceMeasure = DistanceMeasure.Att
+      };
+    }
+  }
+
+  [Item("Manhattan TSP Data", "TSP that is represented by Manhattan coordinates.")]
+  [StorableType("5f1ef9e2-cbd1-400e-8f87-6855f091fc9e")]
+  public class ManhattanTSPData : CoordinatesTSPData {
+    [StorableConstructor]
+    protected ManhattanTSPData(StorableConstructorFlag _) : base(_) { }
+    protected ManhattanTSPData(ManhattanTSPData original, Cloner cloner) : base(original, cloner) { }
+    public ManhattanTSPData() : base() { }
+    public ManhattanTSPData(string name, double[,] coordinates) : base(name, coordinates) { }
+    public ManhattanTSPData(string name, DoubleMatrix coordinates) : base(name, coordinates) { }
+
+    public override IDeepCloneable Clone(Cloner cloner) {
+      return new ManhattanTSPData(this, cloner);
+    }
+
+    public override double GetDistance(double fromX, double fromY, double toX, double toY) {
+      return DistanceHelper.ManhattanDistance(fromX, fromY, toX, toY);
+    }
+
+    public override TSPData Export() {
+      return new TSPData() {
+        Name = name,
+        Description = description,
+        Coordinates = Coordinates.CloneAsMatrix(),
+        Dimension = Coordinates.Rows,
+        DistanceMeasure = DistanceMeasure.Manhattan
+      };
+    }
+  }
+
+  [Item("Manhattan TSP Data", "TSP that is represented by the maximum absolute distance in either x or y coordinates.")]
+  [StorableType("c6294a6c-fe62-4906-9765-4bc306d3e4a8")]
+  public class MaximumTSPData : CoordinatesTSPData {
+    [StorableConstructor]
+    protected MaximumTSPData(StorableConstructorFlag _) : base(_) { }
+    protected MaximumTSPData(MaximumTSPData original, Cloner cloner) : base(original, cloner) { }
+    public MaximumTSPData() : base() { }
+    public MaximumTSPData(string name, double[,] coordinates) : base(name, coordinates) { }
+    public MaximumTSPData(string name, DoubleMatrix coordinates) : base(name, coordinates) { }
+
+    public override IDeepCloneable Clone(Cloner cloner) {
+      return new MaximumTSPData(this, cloner);
+    }
+
+    public override double GetDistance(double fromX, double fromY, double toX, double toY) {
+      return DistanceHelper.MaximumDistance(fromX, fromY, toX, toY);
+    }
+
+    public override TSPData Export() {
+      return new TSPData() {
+        Name = name,
+        Description = description,
+        Coordinates = Coordinates.CloneAsMatrix(),
+        Dimension = Coordinates.Rows,
+        DistanceMeasure = DistanceMeasure.Maximum
       };
     }
