Index: /branches/2521_ProblemRefactoring/HeuristicLab.Optimization/3.3/Results/IResultParameter.cs
===================================================================
--- /branches/2521_ProblemRefactoring/HeuristicLab.Optimization/3.3/Results/IResultParameter.cs	(revision 17524)
+++ /branches/2521_ProblemRefactoring/HeuristicLab.Optimization/3.3/Results/IResultParameter.cs	(revision 17525)
@@ -28,9 +28,10 @@
   public interface IResultDefinition {
     string Name { get; set; }
+    IItem Get(ResultCollection results);
   }
 
   [StorableType("4c0c854b-676d-4ccd-96c4-b06a3d7f2fa1")]
   public interface IResultDefinition<T> : IResultDefinition where T : class, IItem {
-    T Get(ResultCollection results);
+    new T Get(ResultCollection results);
   }
 
Index: /branches/2521_ProblemRefactoring/HeuristicLab.Optimization/3.3/Results/ResultParameter.cs
===================================================================
--- /branches/2521_ProblemRefactoring/HeuristicLab.Optimization/3.3/Results/ResultParameter.cs	(revision 17524)
+++ /branches/2521_ProblemRefactoring/HeuristicLab.Optimization/3.3/Results/ResultParameter.cs	(revision 17525)
@@ -64,5 +64,6 @@
 
     string IResultDefinition.Name { get => ActualName; set => ActualName = value; }
-    T IResultDefinition<T>.Get(ResultCollection results) => results[ActualName].Value as T;
+    T IResultDefinition<T>.Get(ResultCollection results) => ((IResultDefinition)this).Get(results) as T;
+    IItem IResultDefinition.Get(ResultCollection results) => results[ActualName].Value;
 
     [StorableConstructor]
Index: /branches/2521_ProblemRefactoring/HeuristicLab.Problems.Orienteering.Views/3.3/HeuristicLab.Problems.Orienteering.Views-3.3.csproj
===================================================================
--- /branches/2521_ProblemRefactoring/HeuristicLab.Problems.Orienteering.Views/3.3/HeuristicLab.Problems.Orienteering.Views-3.3.csproj	(revision 17524)
+++ /branches/2521_ProblemRefactoring/HeuristicLab.Problems.Orienteering.Views/3.3/HeuristicLab.Problems.Orienteering.Views-3.3.csproj	(revision 17525)
@@ -83,12 +83,20 @@
       <SpecificVersion>False</SpecificVersion>
       <HintPath>..\..\bin\HeuristicLab.Data.Views-3.3.dll</HintPath>
+      <Private>False</Private>
     </Reference>
     <Reference Include="HeuristicLab.Encodings.PermutationEncoding-3.3, Version=3.3.0.0, Culture=neutral, PublicKeyToken=ba48961d6f65dcec, processorArchitecture=MSIL">
       <SpecificVersion>False</SpecificVersion>
       <HintPath>..\..\bin\HeuristicLab.Encodings.PermutationEncoding-3.3.dll</HintPath>
+      <Private>False</Private>
     </Reference>
     <Reference Include="HeuristicLab.Problems.LinearAssignment-3.3, Version=3.3.0.0, Culture=neutral, PublicKeyToken=ba48961d6f65dcec, processorArchitecture=MSIL">
       <SpecificVersion>False</SpecificVersion>
       <HintPath>..\..\bin\HeuristicLab.Problems.LinearAssignment-3.3.dll</HintPath>
+      <Private>False</Private>
+    </Reference>
+    <Reference Include="HeuristicLab.Problems.TravelingSalesman-3.3, Version=3.3.0.0, Culture=neutral, PublicKeyToken=ba48961d6f65dcec, processorArchitecture=MSIL">
+      <SpecificVersion>False</SpecificVersion>
+      <HintPath>..\..\bin\HeuristicLab.Problems.TravelingSalesman-3.3.dll</HintPath>
+      <Private>False</Private>
     </Reference>
     <Reference Include="System" />
@@ -112,4 +120,5 @@
       <DependentUpon>OrienteeringSolutionView.cs</DependentUpon>
     </Compile>
+    <Compile Include="OrienteeringVisualizer.cs" />
     <Compile Include="Plugin.cs" />
     <Compile Include="Properties\AssemblyInfo.cs" />
@@ -124,57 +133,84 @@
       <Project>{A9AD58B9-3EF9-4CC1-97E5-8D909039FF5C}</Project>
       <Name>HeuristicLab.Common-3.3</Name>
+      <Private>False</Private>
     </ProjectReference>
     <ProjectReference Include="..\..\HeuristicLab.Core.Views\3.3\HeuristicLab.Core.Views-3.3.csproj">
       <Project>{E226881D-315F-423D-B419-A766FE0D8685}</Project>
       <Name>HeuristicLab.Core.Views-3.3</Name>
+      <Private>False</Private>
     </ProjectReference>
     <ProjectReference Include="..\..\HeuristicLab.Core\3.3\HeuristicLab.Core-3.3.csproj">
       <Project>{C36BD924-A541-4A00-AFA8-41701378DDC5}</Project>
       <Name>HeuristicLab.Core-3.3</Name>
+      <Private>False</Private>
     </ProjectReference>
     <ProjectReference Include="..\..\HeuristicLab.Data\3.3\HeuristicLab.Data-3.3.csproj">
       <Project>{BBAB9DF5-5EF3-4BA8-ADE9-B36E82114937}</Project>
       <Name>HeuristicLab.Data-3.3</Name>
+      <Private>False</Private>
     </ProjectReference>
     <ProjectReference Include="..\..\HeuristicLab.Encodings.IntegerVectorEncoding\3.3\HeuristicLab.Encodings.IntegerVectorEncoding-3.3.csproj">
       <Project>{DDFB14DD-2A85-493C-A52D-E69729BBAEB0}</Project>
       <Name>HeuristicLab.Encodings.IntegerVectorEncoding-3.3</Name>
+      <Private>False</Private>
     </ProjectReference>
     <ProjectReference Include="..\..\HeuristicLab.MainForm.WindowsForms\3.3\HeuristicLab.MainForm.WindowsForms-3.3.csproj">
       <Project>{AB687BBE-1BFE-476B-906D-44237135431D}</Project>
       <Name>HeuristicLab.MainForm.WindowsForms-3.3</Name>
+      <Private>False</Private>
     </ProjectReference>
     <ProjectReference Include="..\..\HeuristicLab.MainForm\3.3\HeuristicLab.MainForm-3.3.csproj">
       <Project>{3BD61258-31DA-4B09-89C0-4F71FEF5F05A}</Project>
       <Name>HeuristicLab.MainForm-3.3</Name>
+      <Private>False</Private>
     </ProjectReference>
     <ProjectReference Include="..\..\HeuristicLab.Optimization.Views\3.3\HeuristicLab.Optimization.Views-3.3.csproj">
       <Project>{662B4B15-8F4D-4AE5-B3EB-D91C215F5AF2}</Project>
       <Name>HeuristicLab.Optimization.Views-3.3</Name>
+      <Private>False</Private>
     </ProjectReference>
     <ProjectReference Include="..\..\HeuristicLab.Optimization\3.3\HeuristicLab.Optimization-3.3.csproj">
       <Project>{14AB8D24-25BC-400C-A846-4627AA945192}</Project>
       <Name>HeuristicLab.Optimization-3.3</Name>
+      <Private>False</Private>
     </ProjectReference>
     <ProjectReference Include="..\..\HeuristicLab.Parameters\3.3\HeuristicLab.Parameters-3.3.csproj">
       <Project>{56F9106A-079F-4C61-92F6-86A84C2D84B7}</Project>
       <Name>HeuristicLab.Parameters-3.3</Name>
+      <Private>False</Private>
     </ProjectReference>
     <ProjectReference Include="..\..\HeuristicLab.PluginInfrastructure\3.3\HeuristicLab.PluginInfrastructure-3.3.csproj">
       <Project>{94186A6A-5176-4402-AE83-886557B53CCA}</Project>
       <Name>HeuristicLab.PluginInfrastructure-3.3</Name>
+      <Private>False</Private>
     </ProjectReference>
     <ProjectReference Include="..\..\HeuristicLab.Problems.Instances\3.3\HeuristicLab.Problems.Instances-3.3.csproj">
       <Project>{3540E29E-4793-49E7-8EE2-FEA7F61C3994}</Project>
       <Name>HeuristicLab.Problems.Instances-3.3</Name>
+      <Private>False</Private>
     </ProjectReference>
     <ProjectReference Include="..\..\HeuristicLab.Problems.LinearAssignment.Views\3.3\HeuristicLab.Problems.LinearAssignment.Views-3.3.csproj">
       <Project>{8A7C524C-4B72-45FD-8274-EFB67C27C169}</Project>
       <Name>HeuristicLab.Problems.LinearAssignment.Views-3.3</Name>
+      <Private>False</Private>
     </ProjectReference>
     <ProjectReference Include="..\..\HeuristicLab.Problems.Orienteering\3.3\HeuristicLab.Problems.Orienteering-3.3.csproj">
       <Project>{D1EFA4CC-909F-41D5-9C1F-C3AF1957A372}</Project>
       <Name>HeuristicLab.Problems.Orienteering-3.3</Name>
-    </ProjectReference>
+      <Private>False</Private>
+    </ProjectReference>
+    <ProjectReference Include="..\..\HeuristicLab.Problems.TravelingSalesman.Views\3.3\HeuristicLab.Problems.TravelingSalesman.Views-3.3.csproj">
+      <Project>{CDA28124-ACD0-4231-8EB0-C510B361F84E}</Project>
+      <Name>HeuristicLab.Problems.TravelingSalesman.Views-3.3</Name>
+      <Private>False</Private>
+    </ProjectReference>
+  </ItemGroup>
+  <ItemGroup>
+    <EmbeddedResource Include="OrienteeringProblemView.resx">
+      <DependentUpon>OrienteeringProblemView.cs</DependentUpon>
+    </EmbeddedResource>
+    <EmbeddedResource Include="OrienteeringSolutionView.resx">
+      <DependentUpon>OrienteeringSolutionView.cs</DependentUpon>
+    </EmbeddedResource>
   </ItemGroup>
   <Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
Index: /branches/2521_ProblemRefactoring/HeuristicLab.Problems.Orienteering.Views/3.3/OrienteeringProblemView.cs
===================================================================
--- /branches/2521_ProblemRefactoring/HeuristicLab.Problems.Orienteering.Views/3.3/OrienteeringProblemView.cs	(revision 17524)
+++ /branches/2521_ProblemRefactoring/HeuristicLab.Problems.Orienteering.Views/3.3/OrienteeringProblemView.cs	(revision 17525)
@@ -38,9 +38,4 @@
 
     protected override void DeregisterContentEvents() {
-      Content.CoordinatesParameter.ValueChanged -= CoordinatesParameter_ValueChanged;
-      Content.StartingPointParameter.ValueChanged -= StartingPointParameter_ValueChanged;
-      Content.TerminalPointParameter.ValueChanged -= TerminalPointParameter_ValueChanged;
-      Content.ScoresParameter.ValueChanged -= ScoresParameter_ValueChanged;
-      Content.BestKnownQualityParameter.ValueChanged -= BestKnownQualityParameter_ValueChanged;
       Content.BestKnownSolutionParameter.ValueChanged -= BestKnownSolutionParameter_ValueChanged;
       base.DeregisterContentEvents();
@@ -48,9 +43,4 @@
     protected override void RegisterContentEvents() {
       base.RegisterContentEvents();
-      Content.CoordinatesParameter.ValueChanged += CoordinatesParameter_ValueChanged;
-      Content.StartingPointParameter.ValueChanged += StartingPointParameter_ValueChanged;
-      Content.TerminalPointParameter.ValueChanged += TerminalPointParameter_ValueChanged;
-      Content.ScoresParameter.ValueChanged += ScoresParameter_ValueChanged;
-      Content.BestKnownQualityParameter.ValueChanged += BestKnownQualityParameter_ValueChanged;
       Content.BestKnownSolutionParameter.ValueChanged += BestKnownSolutionParameter_ValueChanged;
     }
@@ -61,9 +51,5 @@
         orienteeringSolutionView.Content = null;
       } else {
-        orienteeringSolutionView.Content = new OrienteeringSolution(Content.BestKnownSolution,
-          Content.Coordinates, Content.StartingPointParameter.Value, Content.TerminalPointParameter.Value, Content.Scores);
-        if (Content.BestKnownSolution != null) {
-          EvaluateBestSolution();
-        }
+        orienteeringSolutionView.Content = Content.BestKnownSolution;
       }
     }
@@ -71,44 +57,9 @@
     protected override void SetEnabledStateOfControls() {
       base.SetEnabledStateOfControls();
-      orienteeringSolutionView.Enabled = Content != null;
-    }
-
-    private void CoordinatesParameter_ValueChanged(object sender, EventArgs e) {
-      orienteeringSolutionView.Content.Coordinates = Content.Coordinates;
-    }
-
-    private void StartingPointParameter_ValueChanged(object sender, EventArgs e) {
-      orienteeringSolutionView.Content.StartingPoint.Value = Content.StartingPoint;
-    }
-
-    private void TerminalPointParameter_ValueChanged(object sender, EventArgs e) {
-      orienteeringSolutionView.Content.TerminalPoint.Value = Content.TerminalPoint;
-    }
-
-    private void ScoresParameter_ValueChanged(object sender, EventArgs e) {
-      orienteeringSolutionView.Content.Scores = Content.Scores;
-    }
-
-    private void BestKnownQualityParameter_ValueChanged(object sender, EventArgs e) {
-      orienteeringSolutionView.Content.Quality = Content.BestKnownQuality;
+      orienteeringSolutionView.Enabled = Content != null && !ReadOnly && !Locked;
     }
 
     private void BestKnownSolutionParameter_ValueChanged(object sender, EventArgs e) {
-      orienteeringSolutionView.Content.IntegerVector = Content.BestKnownSolution;
-      if (Content.BestKnownSolution != null)
-        EvaluateBestSolution();
-      else {
-        var solution = orienteeringSolutionView.Content;
-        solution.Penalty = null;
-        solution.Distance = null;
-      }
-    }
-
-    private void EvaluateBestSolution() {
-      var evaluation = Content.Evaluator.Evaluate(Content.BestKnownSolution, Content.Scores, Content.DistanceMatrix,
-        Content.MaximumDistance, Content.PointVisitingCosts);
-      orienteeringSolutionView.Content.Quality = evaluation.Quality;
-      orienteeringSolutionView.Content.Penalty = evaluation.Penalty;
-      orienteeringSolutionView.Content.Distance = evaluation.Distance;
+      orienteeringSolutionView.Content = Content.BestKnownSolution;
     }
   }
Index: /branches/2521_ProblemRefactoring/HeuristicLab.Problems.Orienteering.Views/3.3/OrienteeringProblemView.resx
===================================================================
--- /branches/2521_ProblemRefactoring/HeuristicLab.Problems.Orienteering.Views/3.3/OrienteeringProblemView.resx	(revision 17525)
+++ /branches/2521_ProblemRefactoring/HeuristicLab.Problems.Orienteering.Views/3.3/OrienteeringProblemView.resx	(revision 17525)
@@ -0,0 +1,120 @@
+﻿<?xml version="1.0" encoding="utf-8"?>
+<root>
+  <!-- 
+    Microsoft ResX Schema 
+    
+    Version 2.0
+    
+    The primary goals of this format is to allow a simple XML format 
+    that is mostly human readable. The generation and parsing of the 
+    various data types are done through the TypeConverter classes 
+    associated with the data types.
+    
+    Example:
+    
+    ... ado.net/XML headers & schema ...
+    <resheader name="resmimetype">text/microsoft-resx</resheader>
+    <resheader name="version">2.0</resheader>
+    <resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
+    <resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
+    <data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
+    <data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
+    <data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
+        <value>[base64 mime encoded serialized .NET Framework object]</value>
+    </data>
+    <data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
+        <value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
+        <comment>This is a comment</comment>
+    </data>
+                
+    There are any number of "resheader" rows that contain simple 
+    name/value pairs.
+    
+    Each data row contains a name, and value. The row also contains a 
+    type or mimetype. Type corresponds to a .NET class that support 
+    text/value conversion through the TypeConverter architecture. 
+    Classes that don't support this are serialized and stored with the 
+    mimetype set.
+    
+    The mimetype is used for serialized objects, and tells the 
+    ResXResourceReader how to depersist the object. This is currently not 
+    extensible. For a given mimetype the value must be set accordingly:
+    
+    Note - application/x-microsoft.net.object.binary.base64 is the format 
+    that the ResXResourceWriter will generate, however the reader can 
+    read any of the formats listed below.
+    
+    mimetype: application/x-microsoft.net.object.binary.base64
+    value   : The object must be serialized with 
+            : System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
+            : and then encoded with base64 encoding.
+    
+    mimetype: application/x-microsoft.net.object.soap.base64
+    value   : The object must be serialized with 
+            : System.Runtime.Serialization.Formatters.Soap.SoapFormatter
+            : and then encoded with base64 encoding.
+
+    mimetype: application/x-microsoft.net.object.bytearray.base64
+    value   : The object must be serialized into a byte array 
+            : using a System.ComponentModel.TypeConverter
+            : and then encoded with base64 encoding.
+    -->
+  <xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
+    <xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
+    <xsd:element name="root" msdata:IsDataSet="true">
+      <xsd:complexType>
+        <xsd:choice maxOccurs="unbounded">
+          <xsd:element name="metadata">
+            <xsd:complexType>
+              <xsd:sequence>
+                <xsd:element name="value" type="xsd:string" minOccurs="0" />
+              </xsd:sequence>
+              <xsd:attribute name="name" use="required" type="xsd:string" />
+              <xsd:attribute name="type" type="xsd:string" />
+              <xsd:attribute name="mimetype" type="xsd:string" />
+              <xsd:attribute ref="xml:space" />
+            </xsd:complexType>
+          </xsd:element>
+          <xsd:element name="assembly">
+            <xsd:complexType>
+              <xsd:attribute name="alias" type="xsd:string" />
+              <xsd:attribute name="name" type="xsd:string" />
+            </xsd:complexType>
+          </xsd:element>
+          <xsd:element name="data">
+            <xsd:complexType>
+              <xsd:sequence>
+                <xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
+                <xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
+              </xsd:sequence>
+              <xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
+              <xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
+              <xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
+              <xsd:attribute ref="xml:space" />
+            </xsd:complexType>
+          </xsd:element>
+          <xsd:element name="resheader">
+            <xsd:complexType>
+              <xsd:sequence>
+                <xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
+              </xsd:sequence>
+              <xsd:attribute name="name" type="xsd:string" use="required" />
+            </xsd:complexType>
+          </xsd:element>
+        </xsd:choice>
+      </xsd:complexType>
+    </xsd:element>
+  </xsd:schema>
+  <resheader name="resmimetype">
+    <value>text/microsoft-resx</value>
+  </resheader>
+  <resheader name="version">
+    <value>2.0</value>
+  </resheader>
+  <resheader name="reader">
+    <value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
+  </resheader>
+  <resheader name="writer">
+    <value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
+  </resheader>
+</root>
Index: /branches/2521_ProblemRefactoring/HeuristicLab.Problems.Orienteering.Views/3.3/OrienteeringSolutionView.Designer.cs
===================================================================
--- /branches/2521_ProblemRefactoring/HeuristicLab.Problems.Orienteering.Views/3.3/OrienteeringSolutionView.Designer.cs	(revision 17524)
+++ /branches/2521_ProblemRefactoring/HeuristicLab.Problems.Orienteering.Views/3.3/OrienteeringSolutionView.Designer.cs	(revision 17525)
@@ -45,17 +45,8 @@
     /// </summary>
     private void InitializeComponent() {
-      this.pictureBox = new System.Windows.Forms.PictureBox();
-      this.tabControl = new HeuristicLab.MainForm.WindowsForms.DragOverTabControl();
-      this.visualizationTabPage = new System.Windows.Forms.TabPage();
-      this.valueTabPage = new System.Windows.Forms.TabPage();
-      this.tourGroupBox = new System.Windows.Forms.GroupBox();
-      this.tourViewHost = new HeuristicLab.MainForm.WindowsForms.ViewHost();
-      this.splitContainer = new System.Windows.Forms.SplitContainer();
+      this.ScoreLabel = new System.Windows.Forms.Label();
+      this.qualityLabel = new System.Windows.Forms.Label();
       this.qualityValueView = new HeuristicLab.Data.Views.StringConvertibleValueView();
-      this.distanceValueView = new HeuristicLab.Data.Views.StringConvertibleValueView();
-      this.penaltyValueView = new HeuristicLab.Data.Views.StringConvertibleValueView();
-      this.qualityLabel = new System.Windows.Forms.Label();
-      this.distanceLabel = new System.Windows.Forms.Label();
-      this.penaltyLabel = new System.Windows.Forms.Label();
+      this.scoreValueView = new HeuristicLab.Data.Views.StringConvertibleValueView();
       ((System.ComponentModel.ISupportInitialize)(this.pictureBox)).BeginInit();
       this.tabControl.SuspendLayout();
@@ -67,101 +58,49 @@
       this.splitContainer.Panel2.SuspendLayout();
       this.splitContainer.SuspendLayout();
+      this.qualityGroupBox.SuspendLayout();
       this.SuspendLayout();
       // 
       // pictureBox
       // 
-      this.pictureBox.Anchor = ((System.Windows.Forms.AnchorStyles)((((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom)
-            | System.Windows.Forms.AnchorStyles.Left)
-            | System.Windows.Forms.AnchorStyles.Right)));
-      this.pictureBox.BackColor = System.Drawing.Color.White;
-      this.pictureBox.BorderStyle = System.Windows.Forms.BorderStyle.FixedSingle;
-      this.pictureBox.Location = new System.Drawing.Point(6, 6);
-      this.pictureBox.Name = "pictureBox";
-      this.pictureBox.Size = new System.Drawing.Size(403, 271);
-      this.pictureBox.TabIndex = 0;
-      this.pictureBox.TabStop = false;
-      this.pictureBox.SizeChanged += new System.EventHandler(this.pictureBox_SizeChanged);
+      this.pictureBox.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left)));
+      this.pictureBox.Dock = System.Windows.Forms.DockStyle.Fill;
+      this.pictureBox.Location = new System.Drawing.Point(3, 3);
+      this.pictureBox.Size = new System.Drawing.Size(403, 228);
       // 
       // tabControl
       // 
-      this.tabControl.AllowDrop = true;
-      this.tabControl.Anchor = ((System.Windows.Forms.AnchorStyles)((((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom)
-            | System.Windows.Forms.AnchorStyles.Left)
+      this.tabControl.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left) 
             | System.Windows.Forms.AnchorStyles.Right)));
-      this.tabControl.Controls.Add(this.visualizationTabPage);
-      this.tabControl.Controls.Add(this.valueTabPage);
-      this.tabControl.Location = new System.Drawing.Point(0, 3);
-      this.tabControl.Name = "tabControl";
-      this.tabControl.SelectedIndex = 0;
-      this.tabControl.Size = new System.Drawing.Size(423, 305);
-      this.tabControl.TabIndex = 0;
+      this.tabControl.Location = new System.Drawing.Point(3, 72);
+      this.tabControl.Size = new System.Drawing.Size(417, 260);
       // 
       // visualizationTabPage
       // 
-      this.visualizationTabPage.BackColor = System.Drawing.SystemColors.Window;
-      this.visualizationTabPage.Controls.Add(this.pictureBox);
-      this.visualizationTabPage.Location = new System.Drawing.Point(4, 22);
-      this.visualizationTabPage.Name = "visualizationTabPage";
-      this.visualizationTabPage.Padding = new System.Windows.Forms.Padding(3);
-      this.visualizationTabPage.Size = new System.Drawing.Size(415, 279);
-      this.visualizationTabPage.TabIndex = 0;
-      this.visualizationTabPage.Text = "Visualization";
+      this.visualizationTabPage.Size = new System.Drawing.Size(409, 234);
       // 
       // valueTabPage
       // 
-      this.valueTabPage.BackColor = System.Drawing.SystemColors.Window;
-      this.valueTabPage.Controls.Add(this.tourGroupBox);
-      this.valueTabPage.Location = new System.Drawing.Point(4, 22);
-      this.valueTabPage.Name = "valueTabPage";
-      this.valueTabPage.Padding = new System.Windows.Forms.Padding(3);
-      this.valueTabPage.Size = new System.Drawing.Size(211, 370);
-      this.valueTabPage.TabIndex = 1;
-      this.valueTabPage.Text = "Value";
+      this.valueTabPage.Size = new System.Drawing.Size(409, 234);
       // 
       // tourGroupBox
       // 
-      this.tourGroupBox.Anchor = ((System.Windows.Forms.AnchorStyles)((((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom)
-            | System.Windows.Forms.AnchorStyles.Left)
-            | System.Windows.Forms.AnchorStyles.Right)));
-      this.tourGroupBox.Controls.Add(this.tourViewHost);
-      this.tourGroupBox.Location = new System.Drawing.Point(6, 6);
-      this.tourGroupBox.Name = "tourGroupBox";
-      this.tourGroupBox.Size = new System.Drawing.Size(199, 358);
-      this.tourGroupBox.TabIndex = 0;
-      this.tourGroupBox.TabStop = false;
-      this.tourGroupBox.Text = "Tour";
+      this.tourGroupBox.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left)));
+      this.tourGroupBox.Dock = System.Windows.Forms.DockStyle.Fill;
+      this.tourGroupBox.Location = new System.Drawing.Point(3, 3);
+      this.tourGroupBox.Size = new System.Drawing.Size(403, 228);
       // 
       // tourViewHost
       // 
-      this.tourViewHost.Anchor = ((System.Windows.Forms.AnchorStyles)((((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom)
-            | System.Windows.Forms.AnchorStyles.Left)
-            | System.Windows.Forms.AnchorStyles.Right)));
-      this.tourViewHost.Caption = "View";
-      this.tourViewHost.Content = null;
-      this.tourViewHost.Enabled = false;
-      this.tourViewHost.Location = new System.Drawing.Point(6, 19);
-      this.tourViewHost.Name = "tourViewHost";
-      this.tourViewHost.ReadOnly = false;
-      this.tourViewHost.Size = new System.Drawing.Size(187, 333);
-      this.tourViewHost.TabIndex = 0;
-      this.tourViewHost.ViewsLabelVisible = true;
-      this.tourViewHost.ViewType = null;
+      this.tourViewHost.Size = new System.Drawing.Size(391, 203);
       // 
       // splitContainer
       // 
-      this.splitContainer.Dock = System.Windows.Forms.DockStyle.Fill;
-      this.splitContainer.FixedPanel = System.Windows.Forms.FixedPanel.Panel1;
-      this.splitContainer.Location = new System.Drawing.Point(0, 0);
-      this.splitContainer.Name = "splitContainer";
-      this.splitContainer.Orientation = System.Windows.Forms.Orientation.Horizontal;
       // 
       // splitContainer.Panel1
       // 
-      this.splitContainer.Panel1.Controls.Add(this.penaltyLabel);
-      this.splitContainer.Panel1.Controls.Add(this.distanceLabel);
+      this.splitContainer.Panel1.Controls.Add(this.ScoreLabel);
       this.splitContainer.Panel1.Controls.Add(this.qualityLabel);
       this.splitContainer.Panel1.Controls.Add(this.qualityValueView);
-      this.splitContainer.Panel1.Controls.Add(this.distanceValueView);
-      this.splitContainer.Panel1.Controls.Add(this.penaltyValueView);
+      this.splitContainer.Panel1.Controls.Add(this.scoreValueView);
       this.splitContainer.Panel1.Margin = new System.Windows.Forms.Padding(0, 0, 5, 0);
       this.splitContainer.Panel1MinSize = 0;
@@ -169,12 +108,39 @@
       // splitContainer.Panel2
       // 
-      this.splitContainer.Panel2.Controls.Add(this.tabControl);
-      this.splitContainer.Size = new System.Drawing.Size(423, 402);
-      this.splitContainer.SplitterDistance = 87;
-      this.splitContainer.TabIndex = 0;
+      this.splitContainer.Panel2.Controls.Add(this.qualityGroupBox);
+      this.splitContainer.SplitterDistance = 63;
+      // 
+      // qualityGroupBox
+      // 
+      this.qualityGroupBox.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left) 
+            | System.Windows.Forms.AnchorStyles.Right)));
+      this.qualityGroupBox.Location = new System.Drawing.Point(3, 3);
+      this.qualityGroupBox.Size = new System.Drawing.Size(417, 63);
+      // 
+      // qualityViewHost
+      // 
+      this.qualityViewHost.Size = new System.Drawing.Size(405, 38);
+      // 
+      // ScoreLabel
+      // 
+      this.ScoreLabel.AutoSize = true;
+      this.ScoreLabel.Location = new System.Drawing.Point(7, 38);
+      this.ScoreLabel.Name = "ScoreLabel";
+      this.ScoreLabel.Size = new System.Drawing.Size(38, 13);
+      this.ScoreLabel.TabIndex = 1;
+      this.ScoreLabel.Text = "Score:";
+      // 
+      // qualityLabel
+      // 
+      this.qualityLabel.AutoSize = true;
+      this.qualityLabel.Location = new System.Drawing.Point(7, 11);
+      this.qualityLabel.Name = "qualityLabel";
+      this.qualityLabel.Size = new System.Drawing.Size(42, 13);
+      this.qualityLabel.TabIndex = 1;
+      this.qualityLabel.Text = "Quality:";
       // 
       // qualityValueView
       // 
-      this.qualityValueView.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left)
+      this.qualityValueView.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left) 
             | System.Windows.Forms.AnchorStyles.Right)));
       this.qualityValueView.Caption = "StringConvertibleValue View";
@@ -187,63 +153,21 @@
       this.qualityValueView.TabIndex = 0;
       // 
-      // distanceValueView
+      // scoreValueView
       // 
-      this.distanceValueView.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left)
+      this.scoreValueView.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left) 
             | System.Windows.Forms.AnchorStyles.Right)));
-      this.distanceValueView.Caption = "StringConvertibleValue View";
-      this.distanceValueView.Content = null;
-      this.distanceValueView.LabelVisible = false;
-      this.distanceValueView.Location = new System.Drawing.Point(65, 34);
-      this.distanceValueView.Name = "distanceValueView";
-      this.distanceValueView.ReadOnly = false;
-      this.distanceValueView.Size = new System.Drawing.Size(354, 21);
-      this.distanceValueView.TabIndex = 0;
-      // 
-      // penaltyValueView
-      // 
-      this.penaltyValueView.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left)
-            | System.Windows.Forms.AnchorStyles.Right)));
-      this.penaltyValueView.Caption = "StringConvertibleValue View";
-      this.penaltyValueView.Content = null;
-      this.penaltyValueView.LabelVisible = false;
-      this.penaltyValueView.Location = new System.Drawing.Point(65, 61);
-      this.penaltyValueView.Name = "penaltyValueView";
-      this.penaltyValueView.ReadOnly = false;
-      this.penaltyValueView.Size = new System.Drawing.Size(354, 21);
-      this.penaltyValueView.TabIndex = 0;
-      // 
-      // qualityLabel
-      // 
-      this.qualityLabel.AutoSize = true;
-      this.qualityLabel.Location = new System.Drawing.Point(7, 11);
-      this.qualityLabel.Name = "qualityLabel";
-      this.qualityLabel.Size = new System.Drawing.Size(42, 13);
-      this.qualityLabel.TabIndex = 1;
-      this.qualityLabel.Text = "Quality:";
-      // 
-      // distanceLabel
-      // 
-      this.distanceLabel.AutoSize = true;
-      this.distanceLabel.Location = new System.Drawing.Point(7, 38);
-      this.distanceLabel.Name = "distanceLabel";
-      this.distanceLabel.Size = new System.Drawing.Size(52, 13);
-      this.distanceLabel.TabIndex = 1;
-      this.distanceLabel.Text = "Distance:";
-      // 
-      // penaltyLabel
-      // 
-      this.penaltyLabel.AutoSize = true;
-      this.penaltyLabel.Location = new System.Drawing.Point(7, 64);
-      this.penaltyLabel.Name = "penaltyLabel";
-      this.penaltyLabel.Size = new System.Drawing.Size(45, 13);
-      this.penaltyLabel.TabIndex = 1;
-      this.penaltyLabel.Text = "Penalty:";
+      this.scoreValueView.Caption = "StringConvertibleValue View";
+      this.scoreValueView.Content = null;
+      this.scoreValueView.LabelVisible = false;
+      this.scoreValueView.Location = new System.Drawing.Point(65, 34);
+      this.scoreValueView.Name = "scoreValueView";
+      this.scoreValueView.ReadOnly = false;
+      this.scoreValueView.Size = new System.Drawing.Size(354, 21);
+      this.scoreValueView.TabIndex = 0;
       // 
       // OrienteeringSolutionView
       // 
       this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Inherit;
-      this.Controls.Add(this.splitContainer);
       this.Name = "OrienteeringSolutionView";
-      this.Size = new System.Drawing.Size(423, 402);
       ((System.ComponentModel.ISupportInitialize)(this.pictureBox)).EndInit();
       this.tabControl.ResumeLayout(false);
@@ -256,4 +180,5 @@
       ((System.ComponentModel.ISupportInitialize)(this.splitContainer)).EndInit();
       this.splitContainer.ResumeLayout(false);
+      this.qualityGroupBox.ResumeLayout(false);
       this.ResumeLayout(false);
 
@@ -261,18 +186,8 @@
 
     #endregion
-
-    private System.Windows.Forms.PictureBox pictureBox;
-    private HeuristicLab.MainForm.WindowsForms.DragOverTabControl tabControl;
-    private System.Windows.Forms.TabPage visualizationTabPage;
-    private System.Windows.Forms.TabPage valueTabPage;
-    private System.Windows.Forms.GroupBox tourGroupBox;
-    private HeuristicLab.MainForm.WindowsForms.ViewHost tourViewHost;
-    private System.Windows.Forms.SplitContainer splitContainer;
-    private System.Windows.Forms.Label penaltyLabel;
-    private System.Windows.Forms.Label distanceLabel;
+    private System.Windows.Forms.Label ScoreLabel;
     private System.Windows.Forms.Label qualityLabel;
     private Data.Views.StringConvertibleValueView qualityValueView;
-    private Data.Views.StringConvertibleValueView distanceValueView;
-    private Data.Views.StringConvertibleValueView penaltyValueView;
+    private Data.Views.StringConvertibleValueView scoreValueView;
   }
 }
Index: /branches/2521_ProblemRefactoring/HeuristicLab.Problems.Orienteering.Views/3.3/OrienteeringSolutionView.cs
===================================================================
--- /branches/2521_ProblemRefactoring/HeuristicLab.Problems.Orienteering.Views/3.3/OrienteeringSolutionView.cs	(revision 17524)
+++ /branches/2521_ProblemRefactoring/HeuristicLab.Problems.Orienteering.Views/3.3/OrienteeringSolutionView.cs	(revision 17525)
@@ -20,15 +20,16 @@
 #endregion
 
-using System;
-using System.Drawing;
-using System.Linq;
-using HeuristicLab.Common;
-using HeuristicLab.Core.Views;
+using System.ComponentModel;
 using HeuristicLab.MainForm;
+using HeuristicLab.Problems.TravelingSalesman.Views;
 
 namespace HeuristicLab.Problems.Orienteering.Views {
   [View("OrienteeringSolution View")]
   [Content(typeof(OrienteeringSolution), true)]
-  public partial class OrienteeringSolutionView : ItemView {
+  public partial class OrienteeringSolutionView : TSPSolutionView {
+    public new OrienteeringVisualizer Visualizer {
+      get { return (OrienteeringVisualizer)base.Visualizer; }
+      set { base.Visualizer = value; }
+    }
     public new OrienteeringSolution Content {
       get { return (OrienteeringSolution)base.Content; }
@@ -37,187 +38,48 @@
     public OrienteeringSolutionView() {
       InitializeComponent();
+      Visualizer = new OrienteeringVisualizer();
     }
 
     protected override void DeregisterContentEvents() {
-      Content.QualityChanged -= Content_QualityChanged;
-      Content.PenaltyChanged -= Content_PenaltyChanged;
-      Content.DistanceChanged -= Content_DistanceChanged;
-      Content.CoordinatesChanged -= Content_CoordinatesChanged;
-      Content.StartingPointChanged -= Content_StartingPointChanged;
-      Content.TerminalPointChanged -= Content_TerminalPointChanged;
-      Content.ScoresChanged -= Content_ScoresChanged;
-      Content.IntegerVectorChanged -= Content_IntegerVectorChanged;
+      Content.PropertyChanged -= ContentOnPropertyChanged;
       base.DeregisterContentEvents();
     }
     protected override void RegisterContentEvents() {
       base.RegisterContentEvents();
-      Content.QualityChanged += Content_QualityChanged;
-      Content.PenaltyChanged += Content_PenaltyChanged;
-      Content.DistanceChanged += Content_DistanceChanged;
-      Content.CoordinatesChanged += Content_CoordinatesChanged;
-      Content.StartingPointChanged += Content_StartingPointChanged;
-      Content.TerminalPointChanged += Content_TerminalPointChanged;
-      Content.ScoresChanged += Content_ScoresChanged;
-      Content.IntegerVectorChanged += Content_IntegerVectorChanged;
+      Content.PropertyChanged += ContentOnPropertyChanged;
+    }
+
+    protected override void ContentOnPropertyChanged(object sender, PropertyChangedEventArgs e) {
+      base.ContentOnPropertyChanged(sender, e);
+      switch (e.PropertyName) {
+        case nameof(Content.Quality):
+          qualityValueView.Content = Content.Quality;
+          break;
+        case nameof(Content.Score):
+          scoreValueView.Content = Content.Score;
+          break;
+      }
     }
 
     protected override void OnContentChanged() {
-      base.OnContentChanged();
       if (Content == null) {
         qualityValueView.Content = null;
-        penaltyValueView.Content = null;
-        distanceValueView.Content = null;
+        scoreValueView.Content = null;
         splitContainer.Panel1Collapsed = true;
-        pictureBox.Image = null;
-        tourViewHost.Content = null;
+        Visualizer.Data = null;
+        Visualizer.IsFeasible = false;
       } else {
         qualityValueView.Content = Content.Quality;
-        penaltyValueView.Content = Content.Penalty;
-        distanceValueView.Content = Content.Distance;
-        SetPanelCollapsing();
-        GenerateImage();
-        tourViewHost.Content = Content.IntegerVector;
+        scoreValueView.Content = Content.Score;
+        Visualizer.Data = Content.OPData;
+        Visualizer.IsFeasible = Content.TravelCosts.Value <= Content.OPData.MaximumTravelCosts;
       }
+      base.OnContentChanged();
     }
 
     protected override void SetEnabledStateOfControls() {
       base.SetEnabledStateOfControls();
-      qualityValueView.Enabled = Content != null;
-      penaltyValueView.Enabled = Content != null;
-      distanceValueView.Enabled = Content != null;
-      pictureBox.Enabled = Content != null;
-      tourGroupBox.Enabled = Content != null;
-    }
-
-    private void GenerateImage() {
-      if ((pictureBox.Width > 0) && (pictureBox.Height > 0)) {
-        if (Content == null) {
-          pictureBox.Image = null;
-        } else {
-          var coordinates = Content.Coordinates;
-          var scores = Content.Scores;
-          var integerVector = Content.IntegerVector;
-          var bitmap = new Bitmap(pictureBox.Width, pictureBox.Height);
-
-          if ((coordinates != null) && (coordinates.Rows > 0) && (coordinates.Columns == 2)
-            && (scores != null) && (coordinates.Rows == scores.Length)) {
-            double xMin = double.MaxValue, yMin = double.MaxValue, xMax = double.MinValue, yMax = double.MinValue;
-            for (int i = 0; i < coordinates.Rows; i++) {
-              if (xMin > coordinates[i, 0]) xMin = coordinates[i, 0];
-              if (yMin > coordinates[i, 1]) yMin = coordinates[i, 1];
-              if (xMax < coordinates[i, 0]) xMax = coordinates[i, 0];
-              if (yMax < coordinates[i, 1]) yMax = coordinates[i, 1];
-            }
-
-            int border = 20;
-            double xStep = xMax != xMin ? (pictureBox.Width - 2 * border) / (xMax - xMin) : 1;
-            double yStep = yMax != yMin ? (pictureBox.Height - 2 * border) / (yMax - yMin) : 1;
-
-            Point[] points = new Point[coordinates.Rows];
-            for (int i = 0; i < coordinates.Rows; i++)
-              points[i] = new Point(border + ((int)((coordinates[i, 0] - xMin) * xStep)),
-                                    bitmap.Height - (border + ((int)((coordinates[i, 1] - yMin) * yStep))));
-
-            using (Graphics graphics = Graphics.FromImage(bitmap)) {
-              if (integerVector != null && integerVector.Length > 1) {
-                Point[] tour = new Point[integerVector.Length];
-                for (int i = 0; i < integerVector.Length; i++) {
-                  tour[i] = points[integerVector[i]];
-                }
-                bool visualizePenalty = Content.Penalty != null && Content.Penalty.Value > 0;
-                graphics.DrawLines(visualizePenalty ? Pens.Red : Pens.Black, tour);
-              }
-
-              double scoreMin = scores.Min();
-              double scoreMax = scores.Max();
-              double scoreRange = scoreMax - scoreMin;
-              for (int i = 0; i < points.Length; i++) {
-                double score = scores[i];
-                int size = scoreRange.IsAlmost(0.0)
-                  ? 6
-                  : (int)Math.Round(((score - scoreMin) / scoreRange) * 8 + 2);
-                graphics.FillRectangle(Brushes.Red, points[i].X - size / 2, points[i].Y - size / 2, size, size);
-              }
-              int startingPoint = Content.StartingPoint.Value;
-              int terminalPoint = Content.TerminalPoint.Value;
-              Font font = new Font(FontFamily.GenericSansSerif, 10, FontStyle.Regular);
-              var beginSize = graphics.MeasureString("Begin", font);
-              if (startingPoint >= 0 && startingPoint < points.Length)
-                graphics.DrawString("Begin", font, Brushes.Black, points[startingPoint].X - beginSize.Width, points[startingPoint].Y - beginSize.Height);
-              if (terminalPoint >= 0 && terminalPoint < points.Length)
-                graphics.DrawString("End", font, Brushes.Black, points[terminalPoint].X, points[terminalPoint].Y);
-            }
-          } else {
-            using (Graphics graphics = Graphics.FromImage(bitmap)) {
-              graphics.Clear(Color.White);
-              Font font = new Font(FontFamily.GenericSansSerif, 12, FontStyle.Regular);
-              string text = "No coordinates defined or in wrong format.";
-              SizeF strSize = graphics.MeasureString(text, font);
-              graphics.DrawString(text, font, Brushes.Black, (float)(pictureBox.Width - strSize.Width) / 2.0f, (float)(pictureBox.Height - strSize.Height) / 2.0f);
-            }
-          }
-          pictureBox.Image = bitmap;
-        }
-      }
-    }
-
-    private void SetPanelCollapsing() {
-      splitContainer.Panel1Collapsed = qualityValueView.Content == null && penaltyValueView.Content == null && distanceValueView.Content == null;
-    }
-
-    private void Content_QualityChanged(object sender, EventArgs e) {
-      if (InvokeRequired) Invoke((Action<object, EventArgs>)Content_QualityChanged, sender, e);
-      else {
-        qualityValueView.Content = Content.Quality;
-        SetPanelCollapsing();
-      }
-    }
-    private void Content_PenaltyChanged(object sender, EventArgs e) {
-      if (InvokeRequired) Invoke((Action<object, EventArgs>)Content_PenaltyChanged, sender, e);
-      else {
-        penaltyValueView.Content = Content.Penalty;
-        GenerateImage();
-        SetPanelCollapsing();
-      }
-    }
-
-    private void Content_DistanceChanged(object sender, EventArgs e) {
-      if (InvokeRequired) Invoke((Action<object, EventArgs>)Content_DistanceChanged, sender, e);
-      else {
-        distanceValueView.Content = Content.Distance;
-        SetPanelCollapsing();
-      }
-    }
-
-    private void Content_CoordinatesChanged(object sender, EventArgs e) {
-      if (InvokeRequired) Invoke((Action<object, EventArgs>)Content_CoordinatesChanged, sender, e);
-      else GenerateImage();
-    }
-
-    private void Content_StartingPointChanged(object sender, EventArgs e) {
-      if (InvokeRequired) Invoke((Action<object, EventArgs>)Content_StartingPointChanged, sender, e);
-      else GenerateImage();
-    }
-
-    private void Content_TerminalPointChanged(object sender, EventArgs e) {
-      if (InvokeRequired) Invoke((Action<object, EventArgs>)Content_TerminalPointChanged, sender, e);
-      else GenerateImage();
-    }
-
-    private void Content_ScoresChanged(object sender, EventArgs e) {
-      if (InvokeRequired) Invoke((Action<object, EventArgs>)Content_ScoresChanged, sender, e);
-      else GenerateImage();
-    }
-
-    private void Content_IntegerVectorChanged(object sender, EventArgs e) {
-      if (InvokeRequired) Invoke((Action<object, EventArgs>)Content_IntegerVectorChanged, sender, e);
-      else {
-        GenerateImage();
-        tourViewHost.Content = Content.IntegerVector;
-      }
-    }
-
-    private void pictureBox_SizeChanged(object sender, EventArgs e) {
-      GenerateImage();
+      qualityValueView.Enabled = Content != null && !ReadOnly && !Locked;
+      scoreValueView.Enabled = Content != null && !ReadOnly && !Locked;
     }
   }
Index: /branches/2521_ProblemRefactoring/HeuristicLab.Problems.Orienteering.Views/3.3/OrienteeringSolutionView.resx
===================================================================
--- /branches/2521_ProblemRefactoring/HeuristicLab.Problems.Orienteering.Views/3.3/OrienteeringSolutionView.resx	(revision 17525)
+++ /branches/2521_ProblemRefactoring/HeuristicLab.Problems.Orienteering.Views/3.3/OrienteeringSolutionView.resx	(revision 17525)
@@ -0,0 +1,120 @@
+﻿<?xml version="1.0" encoding="utf-8"?>
+<root>
+  <!-- 
+    Microsoft ResX Schema 
+    
+    Version 2.0
+    
+    The primary goals of this format is to allow a simple XML format 
+    that is mostly human readable. The generation and parsing of the 
+    various data types are done through the TypeConverter classes 
+    associated with the data types.
+    
+    Example:
+    
+    ... ado.net/XML headers & schema ...
+    <resheader name="resmimetype">text/microsoft-resx</resheader>
+    <resheader name="version">2.0</resheader>
+    <resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
+    <resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
+    <data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
+    <data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
+    <data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
+        <value>[base64 mime encoded serialized .NET Framework object]</value>
+    </data>
+    <data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
+        <value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
+        <comment>This is a comment</comment>
+    </data>
+                
+    There are any number of "resheader" rows that contain simple 
+    name/value pairs.
+    
+    Each data row contains a name, and value. The row also contains a 
+    type or mimetype. Type corresponds to a .NET class that support 
+    text/value conversion through the TypeConverter architecture. 
+    Classes that don't support this are serialized and stored with the 
+    mimetype set.
+    
+    The mimetype is used for serialized objects, and tells the 
+    ResXResourceReader how to depersist the object. This is currently not 
+    extensible. For a given mimetype the value must be set accordingly:
+    
+    Note - application/x-microsoft.net.object.binary.base64 is the format 
+    that the ResXResourceWriter will generate, however the reader can 
+    read any of the formats listed below.
+    
+    mimetype: application/x-microsoft.net.object.binary.base64
+    value   : The object must be serialized with 
+            : System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
+            : and then encoded with base64 encoding.
+    
+    mimetype: application/x-microsoft.net.object.soap.base64
+    value   : The object must be serialized with 
+            : System.Runtime.Serialization.Formatters.Soap.SoapFormatter
+            : and then encoded with base64 encoding.
+
+    mimetype: application/x-microsoft.net.object.bytearray.base64
+    value   : The object must be serialized into a byte array 
+            : using a System.ComponentModel.TypeConverter
+            : and then encoded with base64 encoding.
+    -->
+  <xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
+    <xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
+    <xsd:element name="root" msdata:IsDataSet="true">
+      <xsd:complexType>
+        <xsd:choice maxOccurs="unbounded">
+          <xsd:element name="metadata">
+            <xsd:complexType>
+              <xsd:sequence>
+                <xsd:element name="value" type="xsd:string" minOccurs="0" />
+              </xsd:sequence>
+              <xsd:attribute name="name" use="required" type="xsd:string" />
+              <xsd:attribute name="type" type="xsd:string" />
+              <xsd:attribute name="mimetype" type="xsd:string" />
+              <xsd:attribute ref="xml:space" />
+            </xsd:complexType>
+          </xsd:element>
+          <xsd:element name="assembly">
+            <xsd:complexType>
+              <xsd:attribute name="alias" type="xsd:string" />
+              <xsd:attribute name="name" type="xsd:string" />
+            </xsd:complexType>
+          </xsd:element>
+          <xsd:element name="data">
+            <xsd:complexType>
+              <xsd:sequence>
+                <xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
+                <xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
+              </xsd:sequence>
+              <xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
+              <xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
+              <xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
+              <xsd:attribute ref="xml:space" />
+            </xsd:complexType>
+          </xsd:element>
+          <xsd:element name="resheader">
+            <xsd:complexType>
+              <xsd:sequence>
+                <xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
+              </xsd:sequence>
+              <xsd:attribute name="name" type="xsd:string" use="required" />
+            </xsd:complexType>
+          </xsd:element>
+        </xsd:choice>
+      </xsd:complexType>
+    </xsd:element>
+  </xsd:schema>
+  <resheader name="resmimetype">
+    <value>text/microsoft-resx</value>
+  </resheader>
+  <resheader name="version">
+    <value>2.0</value>
+  </resheader>
+  <resheader name="reader">
+    <value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
+  </resheader>
+  <resheader name="writer">
+    <value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
+  </resheader>
+</root>
Index: /branches/2521_ProblemRefactoring/HeuristicLab.Problems.Orienteering.Views/3.3/OrienteeringVisualizer.cs
===================================================================
--- /branches/2521_ProblemRefactoring/HeuristicLab.Problems.Orienteering.Views/3.3/OrienteeringVisualizer.cs	(revision 17525)
+++ /branches/2521_ProblemRefactoring/HeuristicLab.Problems.Orienteering.Views/3.3/OrienteeringVisualizer.cs	(revision 17525)
@@ -0,0 +1,102 @@
+﻿#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.Problems.TravelingSalesman.Views;
+
+namespace HeuristicLab.Problems.Orienteering.Views {
+  public class OrienteeringVisualizer : TSPVisualizer {
+    public IOrienteeringProblemData Data { get; set; }
+    public bool IsFeasible { get; set; }
+
+    public override Bitmap Draw(int width, int height) {
+      var coordinates = Coordinates;
+      var integerVector = Tour;
+      var bitmap = new Bitmap(width, height);
+
+      if ((coordinates != null) && (coordinates.Rows > 0) && (coordinates.Columns == 2)
+        && (coordinates.Rows == Data.RoutingData.Cities)) {
+        double xMin = double.MaxValue, yMin = double.MaxValue, xMax = double.MinValue, yMax = double.MinValue;
+        for (int i = 0; i < coordinates.Rows; i++) {
+          if (xMin > coordinates[i, 0]) xMin = coordinates[i, 0];
+          if (yMin > coordinates[i, 1]) yMin = coordinates[i, 1];
+          if (xMax < coordinates[i, 0]) xMax = coordinates[i, 0];
+          if (yMax < coordinates[i, 1]) yMax = coordinates[i, 1];
+        }
+
+        int border = 20;
+        double xStep = xMax != xMin ? (width - 2 * border) / (xMax - xMin) : 1;
+        double yStep = yMax != yMin ? (height - 2 * border) / (yMax - yMin) : 1;
+
+        Point[] points = new Point[coordinates.Rows];
+        for (int i = 0; i < coordinates.Rows; i++)
+          points[i] = new Point(border + ((int)((coordinates[i, 0] - xMin) * xStep)),
+                                bitmap.Height - (border + ((int)((coordinates[i, 1] - yMin) * yStep))));
+
+        using (Graphics graphics = Graphics.FromImage(bitmap)) {
+          if (integerVector != null && integerVector.Length > 1) {
+            Point[] tour = new Point[integerVector.Length];
+            for (int i = 0; i < integerVector.Length; i++) {
+              tour[i] = points[integerVector[i]];
+            }
+            bool visualizePenalty = !IsFeasible;
+            graphics.DrawLines(visualizePenalty ? Pens.Red : Pens.Black, tour);
+          }
+
+          double scoreMin = double.MaxValue;
+          double scoreMax = double.MinValue;
+          for (int i = 0; i < points.Length; i++) {
+            var score = Data.GetScore(i);
+            if (score < scoreMin) scoreMin = score;
+            if (score > scoreMax) scoreMax = score;
+          }
+          double scoreRange = scoreMax - scoreMin;
+          for (int i = 0; i < points.Length; i++) {
+            double score = Data.GetScore(i);
+            int size = scoreRange.IsAlmost(0.0)
+              ? 6
+              : (int)Math.Round(((score - scoreMin) / scoreRange) * 8 + 2);
+            graphics.FillRectangle(Brushes.Red, points[i].X - size / 2, points[i].Y - size / 2, size, size);
+          }
+          int startingPoint = Data.StartingPoint;
+          int terminalPoint = Data.TerminalPoint;
+          Font font = new Font(FontFamily.GenericSansSerif, 10, FontStyle.Regular);
+          var beginSize = graphics.MeasureString("Begin", font);
+          if (startingPoint >= 0 && startingPoint < points.Length)
+            graphics.DrawString("Begin", font, Brushes.Black, points[startingPoint].X - beginSize.Width, points[startingPoint].Y - beginSize.Height);
+          if (terminalPoint >= 0 && terminalPoint < points.Length)
+            graphics.DrawString("End", font, Brushes.Black, points[terminalPoint].X, points[terminalPoint].Y);
+        }
+      } else {
+        using (Graphics graphics = Graphics.FromImage(bitmap)) {
+          graphics.Clear(Color.White);
+          Font font = new Font(FontFamily.GenericSansSerif, 12, FontStyle.Regular);
+          string text = "No coordinates defined or in wrong format.";
+          SizeF strSize = graphics.MeasureString(text, font);
+          graphics.DrawString(text, font, Brushes.Black, (float)(width - strSize.Width) / 2.0f, (float)(height - strSize.Height) / 2.0f);
+        }
+      }
+      return bitmap;
+    }
+  }
+}
Index: /branches/2521_ProblemRefactoring/HeuristicLab.Problems.Orienteering/3.3/Creators/GreedyOrienteeringTourCreator.cs
===================================================================
--- /branches/2521_ProblemRefactoring/HeuristicLab.Problems.Orienteering/3.3/Creators/GreedyOrienteeringTourCreator.cs	(revision 17524)
+++ /branches/2521_ProblemRefactoring/HeuristicLab.Problems.Orienteering/3.3/Creators/GreedyOrienteeringTourCreator.cs	(revision 17525)
@@ -22,4 +22,5 @@
 using System.Collections.Generic;
 using System.Linq;
+using HEAL.Attic;
 using HeuristicLab.Common;
 using HeuristicLab.Core;
@@ -27,5 +28,4 @@
 using HeuristicLab.Encodings.IntegerVectorEncoding;
 using HeuristicLab.Parameters;
-using HEAL.Attic;
 
 namespace HeuristicLab.Problems.Orienteering {
@@ -43,24 +43,7 @@
     public override bool CanChangeName { get { return false; } }
 
-    #region Parameter Properties
-    public ILookupParameter<DistanceMatrix> DistanceMatrixParameter {
-      get { return (ILookupParameter<DistanceMatrix>)Parameters["DistanceMatrix"]; }
+    public ILookupParameter<IOrienteeringProblemData> OrienteeringProblemDataParameter {
+      get { return (ILookupParameter<IOrienteeringProblemData>)Parameters["OrienteeringProblemData"]; }
     }
-    public ILookupParameter<DoubleArray> ScoresParameter {
-      get { return (ILookupParameter<DoubleArray>)Parameters["Scores"]; }
-    }
-    public ILookupParameter<DoubleValue> MaximumDistanceParameter {
-      get { return (ILookupParameter<DoubleValue>)Parameters["MaximumDistance"]; }
-    }
-    public ILookupParameter<IntValue> StartingPointParameter {
-      get { return (ILookupParameter<IntValue>)Parameters["StartingPoint"]; }
-    }
-    public ILookupParameter<IntValue> TerminalPointParameter {
-      get { return (ILookupParameter<IntValue>)Parameters["TerminalPoint"]; }
-    }
-    public ILookupParameter<DoubleValue> PointVisitingCostsParameter {
-      get { return (ILookupParameter<DoubleValue>)Parameters["PointVisitingCosts"]; }
-    }
-    #endregion
 
     [StorableConstructor]
@@ -71,10 +54,5 @@
     public GreedyOrienteeringTourCreator()
       : base() {
-      Parameters.Add(new LookupParameter<DistanceMatrix>("DistanceMatrix", "The matrix which contains the distances between the points."));
-      Parameters.Add(new LookupParameter<DoubleArray>("Scores", "The scores of the points."));
-      Parameters.Add(new LookupParameter<DoubleValue>("MaximumDistance", "The maximum distance constraint for a Orienteering solution."));
-      Parameters.Add(new LookupParameter<IntValue>("StartingPoint", "Index of the starting point."));
-      Parameters.Add(new LookupParameter<IntValue>("TerminalPoint", "Index of the ending point."));
-      Parameters.Add(new LookupParameter<DoubleValue>("PointVisitingCosts", "The costs for visiting a point."));
+      Parameters.Add(new LookupParameter<IOrienteeringProblemData>("OrienteeringProblemData", "The main data that comprises the orienteering problem."));
     }
 
@@ -84,19 +62,14 @@
 
     protected override IntegerVector Create(IRandom random, IntValue length, IntMatrix bounds) {
-      int startPoint = StartingPointParameter.ActualValue.Value;
-      int endPoint = TerminalPointParameter.ActualValue.Value;
-      int numPoints = ScoresParameter.ActualValue.Length;
-      var distances = DistanceMatrixParameter.ActualValue;
-      double pointVisitingCosts = PointVisitingCostsParameter.ActualValue.Value;
-      double maxDistance = MaximumDistanceParameter.ActualValue.Value;
-      var scores = ScoresParameter.ActualValue;
+      var data = OrienteeringProblemDataParameter.ActualValue;
 
       // Find all points within the maximum distance allowed (ellipse)
       var feasiblePoints = (
-        from point in Enumerable.Range(0, numPoints)
-        let distance = distances[startPoint, point] + distances[point, endPoint] + pointVisitingCosts
-        let score = scores[point]
-        where distance <= maxDistance
-        where point != startPoint && point != endPoint
+        from point in Enumerable.Range(0, data.RoutingData.Cities)
+        let travelCosts = data.RoutingData.GetDistance(data.StartingPoint, point)
+        + data.RoutingData.GetDistance(point, data.TerminalPoint) + data.PointVisitingCosts
+        let score = data.GetScore(point)
+        where travelCosts <= data.MaximumTravelCosts
+        where point != data.StartingPoint && point != data.TerminalPoint
         orderby score descending
         select point
@@ -105,8 +78,8 @@
       // Add the starting and terminus point
       var tour = new List<int> {
-        startPoint,
-        endPoint
+        data.StartingPoint,
+        data.TerminalPoint
       };
-      double tourLength = distances[startPoint, endPoint];
+      double tourLength = data.RoutingData.GetDistance(data.StartingPoint, data.TerminalPoint);
 
       // Add points in a greedy way
@@ -118,8 +91,8 @@
           for (int insertPosition = 1; insertPosition < tour.Count; insertPosition++) {
             // Create the candidate tour
-            double detour = distances.CalculateInsertionCosts(tour, insertPosition, feasiblePoints[i], pointVisitingCosts);
+            double detour = OrienteeringProblem.CalculateInsertionCosts(data, tour, insertPosition, feasiblePoints[i]);
 
             // If the insertion would be feasible, perform it
-            if (tourLength + detour <= maxDistance) {
+            if (tourLength + detour <= data.MaximumTravelCosts) {
               tour.Insert(insertPosition, feasiblePoints[i]);
               tourLength += detour;
Index: /branches/2521_ProblemRefactoring/HeuristicLab.Problems.Orienteering/3.3/DistanceMatrix.cs
===================================================================
--- /branches/2521_ProblemRefactoring/HeuristicLab.Problems.Orienteering/3.3/DistanceMatrix.cs	(revision 17524)
+++ /branches/2521_ProblemRefactoring/HeuristicLab.Problems.Orienteering/3.3/DistanceMatrix.cs	(revision 17525)
@@ -22,8 +22,8 @@
 using System;
 using System.Collections.Generic;
+using HEAL.Attic;
 using HeuristicLab.Common;
 using HeuristicLab.Core;
 using HeuristicLab.Data;
-using HEAL.Attic;
 
 namespace HeuristicLab.Problems.Orienteering {
@@ -67,10 +67,10 @@
       return detour;
     }
-    public double CalculateReplacementCosts(List<int> path, int replacePosition, int point) {
+    public double CalculateReplacementCosts(IList<int> path, int replacePosition, int point) {
       double detour = this[path[replacePosition - 1], point] + this[point, path[replacePosition + 1]];
       detour -= this[path[replacePosition - 1], path[replacePosition]] + this[path[replacePosition], path[replacePosition + 1]];
       return detour;
     }
-    public double CalculateRemovementSaving(List<int> path, int removePosition, double pointVisitingCosts) {
+    public double CalculateRemovementSaving(IList<int> path, int removePosition, double pointVisitingCosts) {
       double saving = this[path[removePosition - 1], path[removePosition]];
       saving += this[path[removePosition], path[removePosition + 1]];
Index: /branches/2521_ProblemRefactoring/HeuristicLab.Problems.Orienteering/3.3/HeuristicLab.Problems.Orienteering-3.3.csproj
===================================================================
--- /branches/2521_ProblemRefactoring/HeuristicLab.Problems.Orienteering/3.3/HeuristicLab.Problems.Orienteering-3.3.csproj	(revision 17524)
+++ /branches/2521_ProblemRefactoring/HeuristicLab.Problems.Orienteering/3.3/HeuristicLab.Problems.Orienteering-3.3.csproj	(revision 17525)
@@ -89,12 +89,9 @@
   </ItemGroup>
   <ItemGroup>
-    <Compile Include="Analyzers\BestOrienteeringSolutionAnalyzer.cs" />
     <Compile Include="Creators\GreedyOrienteeringTourCreator.cs" />
     <Compile Include="DistanceMatrix.cs" />
-    <Compile Include="OrienteeringEvaluationResult.cs" />
     <Compile Include="Improvers\OrienteeringLocalImprovementOperator.cs" />
-    <Compile Include="Interfaces\IOrienteeringEvaluator.cs" />
-    <Compile Include="Evaluators\OrienteeringEvaluator.cs" />
     <Compile Include="Interfaces\IOrienteeringSolutionCreator.cs" />
+    <Compile Include="OrienteeringProblemData.cs" />
     <Compile Include="OrienteeringProblem.cs" />
     <Compile Include="OrienteeringSolution.cs" />
@@ -144,4 +141,9 @@
       <Private>False</Private>
     </ProjectReference>
+    <ProjectReference Include="..\..\HeuristicLab.Encodings.PermutationEncoding\3.3\HeuristicLab.Encodings.PermutationEncoding-3.3.csproj">
+      <Project>{DBECB8B0-B166-4133-BAF1-ED67C3FD7FCA}</Project>
+      <Name>HeuristicLab.Encodings.PermutationEncoding-3.3</Name>
+      <Private>False</Private>
+    </ProjectReference>
     <ProjectReference Include="..\..\HeuristicLab.Operators\3.3\HeuristicLab.Operators-3.3.csproj">
       <Project>{23DA7FF4-D5B8-41B6-AA96-F0561D24F3EE}</Project>
@@ -179,4 +181,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>
@@ -197,4 +204,5 @@
     </Reference>
   </ItemGroup>
+  <ItemGroup />
   <Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
   <PropertyGroup>
Index: /branches/2521_ProblemRefactoring/HeuristicLab.Problems.Orienteering/3.3/Improvers/OrienteeringLocalImprovementOperator.cs
===================================================================
--- /branches/2521_ProblemRefactoring/HeuristicLab.Problems.Orienteering/3.3/Improvers/OrienteeringLocalImprovementOperator.cs	(revision 17524)
+++ /branches/2521_ProblemRefactoring/HeuristicLab.Problems.Orienteering/3.3/Improvers/OrienteeringLocalImprovementOperator.cs	(revision 17525)
@@ -22,4 +22,5 @@
 using System.Collections.Generic;
 using System.Linq;
+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.Orienteering {
@@ -45,22 +45,8 @@
       get { return (ILookupParameter<IntegerVector>)Parameters["OrienteeringSolution"]; }
     }
-    public ILookupParameter<DistanceMatrix> DistanceMatrixParameter {
-      get { return (ILookupParameter<DistanceMatrix>)Parameters["DistanceMatrix"]; }
-    }
-    public ILookupParameter<DoubleArray> ScoresParameter {
-      get { return (ILookupParameter<DoubleArray>)Parameters["Scores"]; }
-    }
-    public ILookupParameter<DoubleValue> MaximumDistanceParameter {
-      get { return (ILookupParameter<DoubleValue>)Parameters["MaximumDistance"]; }
-    }
-    public ILookupParameter<IntValue> StartingPointParameter {
-      get { return (ILookupParameter<IntValue>)Parameters["StartingPoint"]; }
-    }
-    public ILookupParameter<IntValue> TerminalPointParameter {
-      get { return (ILookupParameter<IntValue>)Parameters["TerminalPoint"]; }
-    }
-    public ILookupParameter<DoubleValue> PointVisitingCostsParameter {
-      get { return (ILookupParameter<DoubleValue>)Parameters["PointVisitingCosts"]; }
-    }
+    public ILookupParameter<IOrienteeringProblemData> OrienteeringProblemDataParameter {
+      get { return (ILookupParameter<IOrienteeringProblemData>)Parameters["OrienteeringProblemData"]; }
+    }
+
     #region ILocalImprovementOperator Parameters
     public IValueLookupParameter<IntValue> LocalIterationsParameter {
@@ -96,10 +82,5 @@
       : base() {
       Parameters.Add(new LookupParameter<IntegerVector>("OrienteeringSolution", "The Orienteering Solution given in path representation."));
-      Parameters.Add(new LookupParameter<DistanceMatrix>("DistanceMatrix", "The matrix which contains the distances between the points."));
-      Parameters.Add(new LookupParameter<DoubleArray>("Scores", "The scores of the points."));
-      Parameters.Add(new LookupParameter<DoubleValue>("MaximumDistance", "The maximum distance constraint for a Orienteering solution."));
-      Parameters.Add(new LookupParameter<IntValue>("StartingPoint", "Index of the starting point."));
-      Parameters.Add(new LookupParameter<IntValue>("TerminalPoint", "Index of the ending point."));
-      Parameters.Add(new LookupParameter<DoubleValue>("PointVisitingCosts", "The costs for visiting a point."));
+      Parameters.Add(new LookupParameter<IOrienteeringProblemData>("OrienteeringProblemData", "The main data that comprises the orienteering problem."));
 
       Parameters.Add(new ValueLookupParameter<IntValue>("LocalIterations", "The number of iterations that have already been performed.", new IntValue(0)));
@@ -118,9 +99,5 @@
 
     public override IOperation Apply() {
-      int numPoints = ScoresParameter.ActualValue.Length;
-      var distances = DistanceMatrixParameter.ActualValue;
-      var scores = ScoresParameter.ActualValue;
-      double pointVisitingCosts = PointVisitingCostsParameter.ActualValue.Value;
-      double maxLength = MaximumDistanceParameter.ActualValue.Value;
+      var data = OrienteeringProblemDataParameter.ActualValue;
       int maxIterations = MaximumIterationsParameter.ActualValue.Value;
       int maxBlockLength = MaximumBlockLengthParmeter.Value.Value;
@@ -132,5 +109,5 @@
 
       double tourLength = 0;
-      double tourScore = tour.Sum(point => scores[point]);
+      double tourScore = tour.Sum(point => data.GetScore(point));
 
       var localIterations = LocalIterationsParameter.ActualValue;
@@ -143,21 +120,17 @@
 
         if (localIterations.Value == 0)
-          tourLength = distances.CalculateTourLength(tour, pointVisitingCosts);
+          tourLength = OrienteeringProblem.CalculateTravelCosts(data, tour);
 
         // Try to shorten the path
-        ShortenPath(tour, distances, maxBlockLength, useMaxBlockLength, ref tourLength, ref evaluations);
+        ShortenPath(tour, data, maxBlockLength, useMaxBlockLength, ref tourLength, ref evaluations);
 
         // Determine all points that have not yet been visited by this tour
-        var visitablePoints = Enumerable.Range(0, numPoints).Except(tour).ToList();
+        var visitablePoints = Enumerable.Range(0, data.RoutingData.Cities).Except(tour).ToList();
 
         // Determine if any of the visitable points can be included at any position within the tour
-        IncludeNewPoints(tour, visitablePoints,
-          distances, pointVisitingCosts, maxLength, scores,
-          ref tourLength, ref tourScore, ref evaluations, ref solutionChanged);
+        IncludeNewPoints(tour, visitablePoints, data, ref tourLength, ref tourScore, ref evaluations, ref solutionChanged);
 
         // Determine if any of the visitable points can take the place of an already visited point in the tour to improve the scores
-        ReplacePoints(tour, visitablePoints,
-          distances, maxLength, scores,
-          ref tourLength, ref tourScore, ref evaluations, ref solutionChanged);
+        ReplacePoints(tour, visitablePoints, data, ref tourLength, ref tourScore, ref evaluations, ref solutionChanged);
 
         localIterations.Value++;
@@ -174,5 +147,5 @@
     }
 
-    private void ShortenPath(List<int> tour, DistanceMatrix distances, int maxBlockLength, bool useMaxBlockLength, ref double tourLength, ref int evaluations) {
+    private void ShortenPath(List<int> tour, IOrienteeringProblemData data, int maxBlockLength, bool useMaxBlockLength, ref double tourLength, ref int evaluations) {
       bool solutionChanged;
       int pathSize = tour.Count;
@@ -195,8 +168,8 @@
             double newLength = tourLength;
             // Recalculate length of whole swapped part, in case distances are not symmetric
-            for (int index = position - 1; index < position + blockLength; index++) newLength -= distances[tour[index], tour[index + 1]];
-            for (int index = position + blockLength - 1; index > position; index--) newLength += distances[tour[index], tour[index - 1]];
-            newLength += distances[tour[position - 1], tour[position + blockLength - 1]];
-            newLength += distances[tour[position], tour[position + blockLength]];
+            for (int index = position - 1; index < position + blockLength; index++) newLength -= data.RoutingData.GetDistance(tour[index], tour[index + 1]);
+            for (int index = position + blockLength - 1; index > position; index--) newLength += data.RoutingData.GetDistance(tour[index], tour[index - 1]);
+            newLength += data.RoutingData.GetDistance(tour[position - 1], tour[position + blockLength - 1]);
+            newLength += data.RoutingData.GetDistance(tour[position], tour[position + blockLength]);
 
             if (newLength < tourLength - 0.00001) {
@@ -217,6 +190,5 @@
     }
 
-    private void IncludeNewPoints(List<int> tour, List<int> visitablePoints,
-      DistanceMatrix distances, double pointVisitingCosts, double maxLength, DoubleArray scores,
+    private void IncludeNewPoints(List<int> tour, List<int> visitablePoints, IOrienteeringProblemData data,
       ref double tourLength, ref double tourScore, ref int evaluations, ref bool solutionChanged) {
 
@@ -231,8 +203,8 @@
           evaluations++;
 
-          double detour = distances.CalculateInsertionCosts(tour, tourPosition, visitablePoints[i], pointVisitingCosts);
+          double detour = OrienteeringProblem.CalculateInsertionCosts(data, tour, tourPosition, visitablePoints[i]);
 
           // Determine if including the point does not violate any constraint
-          if (tourLength + detour <= maxLength) {
+          if (tourLength + detour <= data.MaximumTravelCosts) {
             // Insert the new point at this position
             tour.Insert(tourPosition, visitablePoints[i]);
@@ -240,5 +212,5 @@
             // Update the overall tour tourLength and score
             tourLength += detour;
-            tourScore += scores[visitablePoints[i]];
+            tourScore += data.GetScore(visitablePoints[i]);
 
             // Re-run this optimization
@@ -249,6 +221,5 @@
     }
 
-    private void ReplacePoints(List<int> tour, List<int> visitablePoints,
-      DistanceMatrix distances, double maxLength, DoubleArray scores,
+    private void ReplacePoints(List<int> tour, List<int> visitablePoints, IOrienteeringProblemData data,
       ref double tourLength, ref double tourScore, ref int evaluations, ref bool solutionChanged) {
 
@@ -263,10 +234,10 @@
           evaluations++;
 
-          double detour = distances.CalculateReplacementCosts(tour, tourPosition, visitablePoints[i]);
-
-          double oldPointScore = scores[tour[tourPosition]];
-          double newPointScore = scores[visitablePoints[i]];
-
-          if ((tourLength + detour <= maxLength) && (newPointScore > oldPointScore)) {
+          double detour = OrienteeringProblem.CalculateReplacementCosts(data, tour, tourPosition, visitablePoints[i]);
+
+          double oldPointScore = data.GetScore(tour[tourPosition]);
+          double newPointScore = data.GetScore(visitablePoints[i]);
+
+          if ((tourLength + detour <= data.MaximumTravelCosts) && (newPointScore > oldPointScore)) {
             // Replace the old point by the new one
             tour[tourPosition] = visitablePoints[i];
Index: anches/2521_ProblemRefactoring/HeuristicLab.Problems.Orienteering/3.3/Interfaces/IOrienteeringEvaluator.cs
===================================================================
--- /branches/2521_ProblemRefactoring/HeuristicLab.Problems.Orienteering/3.3/Interfaces/IOrienteeringEvaluator.cs	(revision 17524)
+++ 	(revision )
@@ -1,41 +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 HeuristicLab.Core;
-using HeuristicLab.Data;
-using HeuristicLab.Encodings.IntegerVectorEncoding;
-using HeuristicLab.Optimization;
-using HEAL.Attic;
-
-namespace HeuristicLab.Problems.Orienteering {
-  [StorableType("4F942163-D321-4935-BF2E-780193BE9FFE")]
-  public interface IOrienteeringEvaluator : ISingleObjectiveEvaluator {
-    ILookupParameter<IntegerVector> IntegerVectorParameter { get; }
-    ILookupParameter<DoubleArray> ScoresParameter { get; }
-    ILookupParameter<DistanceMatrix> DistanceMatrixParameter { get; }
-    ILookupParameter<DoubleValue> MaximumDistanceParameter { get; }
-    ILookupParameter<DoubleValue> PointVisitingCostsParameter { get; }
-    ILookupParameter<DoubleValue> PenaltyParameter { get; }
-
-    OrienteeringEvaluationResult Evaluate(IntegerVector solution, DoubleArray scores,
-      DistanceMatrix distances, double maximumDistance, double pointVisitingCosts);
-  }
-}
Index: /branches/2521_ProblemRefactoring/HeuristicLab.Problems.Orienteering/3.3/Interfaces/IOrienteeringSolutionCreator.cs
===================================================================
--- /branches/2521_ProblemRefactoring/HeuristicLab.Problems.Orienteering/3.3/Interfaces/IOrienteeringSolutionCreator.cs	(revision 17524)
+++ /branches/2521_ProblemRefactoring/HeuristicLab.Problems.Orienteering/3.3/Interfaces/IOrienteeringSolutionCreator.cs	(revision 17525)
@@ -20,18 +20,12 @@
 #endregion
 
+using HEAL.Attic;
 using HeuristicLab.Core;
-using HeuristicLab.Data;
 using HeuristicLab.Encodings.IntegerVectorEncoding;
-using HEAL.Attic;
 
 namespace HeuristicLab.Problems.Orienteering {
   [StorableType("7E0D4527-4D8C-4FBA-BB3A-26F20B6463ED")]
   public interface IOrienteeringSolutionCreator : IIntegerVectorCreator {
-    ILookupParameter<DistanceMatrix> DistanceMatrixParameter { get; }
-    ILookupParameter<DoubleArray> ScoresParameter { get; }
-    ILookupParameter<DoubleValue> MaximumDistanceParameter { get; }
-    ILookupParameter<IntValue> StartingPointParameter { get; }
-    ILookupParameter<IntValue> TerminalPointParameter { get; }
-    ILookupParameter<DoubleValue> PointVisitingCostsParameter { get; }
+    ILookupParameter<IOrienteeringProblemData> OrienteeringProblemDataParameter { get; }
   }
 }
Index: anches/2521_ProblemRefactoring/HeuristicLab.Problems.Orienteering/3.3/OrienteeringEvaluationResult.cs
===================================================================
--- /branches/2521_ProblemRefactoring/HeuristicLab.Problems.Orienteering/3.3/OrienteeringEvaluationResult.cs	(revision 17524)
+++ 	(revision )
@@ -1,41 +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 HeuristicLab.Data;
-using HEAL.Attic;
-
-namespace HeuristicLab.Problems.Orienteering {
-  [StorableType("A7F34447-A3C9-4FB5-B52F-5143434B4084")]
-  public class OrienteeringEvaluationResult {
-    [Storable]
-    public DoubleValue Quality;
-    [Storable]
-    public DoubleValue Penalty;
-    [Storable]
-    public DoubleValue Distance;
-
-    [StorableConstructor]
-    protected OrienteeringEvaluationResult(StorableConstructorFlag _) {
-    }
-
-    public OrienteeringEvaluationResult() { }
-  }
-}
Index: /branches/2521_ProblemRefactoring/HeuristicLab.Problems.Orienteering/3.3/OrienteeringProblem.cs
===================================================================
--- /branches/2521_ProblemRefactoring/HeuristicLab.Problems.Orienteering/3.3/OrienteeringProblem.cs	(revision 17524)
+++ /branches/2521_ProblemRefactoring/HeuristicLab.Problems.Orienteering/3.3/OrienteeringProblem.cs	(revision 17525)
@@ -20,18 +20,19 @@
 #endregion
 
-using System;
+using System.Collections.Generic;
 using System.IO;
 using System.Linq;
+using System.Threading;
+using HEAL.Attic;
 using HeuristicLab.Analysis;
 using HeuristicLab.Common;
 using HeuristicLab.Core;
-using HeuristicLab.Data;
 using HeuristicLab.Encodings.IntegerVectorEncoding;
 using HeuristicLab.Optimization;
 using HeuristicLab.Optimization.Operators;
 using HeuristicLab.Parameters;
-using HEAL.Attic;
 using HeuristicLab.Problems.Instances;
 using HeuristicLab.Problems.Instances.Types;
+using HeuristicLab.Problems.TravelingSalesman;
 
 namespace HeuristicLab.Problems.Orienteering {
@@ -39,76 +40,20 @@
   [Creatable(CreatableAttribute.Categories.CombinatorialProblems, Priority = 115)]
   [StorableType("0B8DB4A4-F183-4368-86C6-C51289B183D2")]
-  public sealed class OrienteeringProblem
-    : SingleObjectiveHeuristicOptimizationProblem<IOrienteeringEvaluator, IOrienteeringSolutionCreator>,
-    IStorableContent, IProblemInstanceConsumer<OPData>, IProblemInstanceConsumer<TSPData>, IProblemInstanceConsumer<CVRPData> {
-
-    public string Filename { get; set; }
-
-    #region Parameter Properties
-    public OptionalValueParameter<DoubleMatrix> CoordinatesParameter {
-      get { return (OptionalValueParameter<DoubleMatrix>)Parameters["Coordinates"]; }
-    }
-    public IValueParameter<DistanceMatrix> DistanceMatrixParameter {
-      get { return (IValueParameter<DistanceMatrix>)Parameters["DistanceMatrix"]; }
-    }
-
-    public IFixedValueParameter<IntValue> StartingPointParameter {
-      get { return (IFixedValueParameter<IntValue>)Parameters["StartingPoint"]; }
-    }
-    public IFixedValueParameter<IntValue> TerminalPointParameter {
-      get { return (IFixedValueParameter<IntValue>)Parameters["TerminalPoint"]; }
-    }
-    public IFixedValueParameter<DoubleValue> MaximumDistanceParameter {
-      get { return (IFixedValueParameter<DoubleValue>)Parameters["MaximumDistance"]; }
-    }
-    public IValueParameter<DoubleArray> ScoresParameter {
-      get { return (IValueParameter<DoubleArray>)Parameters["Scores"]; }
-    }
-    public IFixedValueParameter<DoubleValue> PointVisitingCostsParameter {
-      get { return (IFixedValueParameter<DoubleValue>)Parameters["PointVisitingCosts"]; }
-    }
-
-    public OptionalValueParameter<IntegerVector> BestKnownSolutionParameter {
-      get { return (OptionalValueParameter<IntegerVector>)Parameters["BestKnownSolution"]; }
-    }
-    #endregion
-
-    #region Properties
-    public DoubleMatrix Coordinates {
-      get { return CoordinatesParameter.Value; }
-      set { CoordinatesParameter.Value = value; }
-    }
-    public DistanceMatrix DistanceMatrix {
-      get { return DistanceMatrixParameter.Value; }
-      set { DistanceMatrixParameter.Value = value; }
-    }
-    public int StartingPoint {
-      get { return StartingPointParameter.Value.Value; }
-      set { StartingPointParameter.Value.Value = value; }
-    }
-    public int TerminalPoint {
-      get { return TerminalPointParameter.Value.Value; }
-      set { TerminalPointParameter.Value.Value = value; }
-    }
-    public double MaximumDistance {
-      get { return MaximumDistanceParameter.Value.Value; }
-      set { MaximumDistanceParameter.Value.Value = value; }
-    }
-    public DoubleArray Scores {
-      get { return ScoresParameter.Value; }
-      set { ScoresParameter.Value = value; }
-    }
-    public double PointVisitingCosts {
-      get { return PointVisitingCostsParameter.Value.Value; }
-      set { PointVisitingCostsParameter.Value.Value = value; }
-    }
-    public IntegerVector BestKnownSolution {
+  public sealed class OrienteeringProblem : IntegerVectorProblem,
+      IProblemInstanceConsumer<OPData>, IProblemInstanceConsumer<TSPData>, IProblemInstanceConsumer<CVRPData> {
+
+    [Storable] public ValueParameter<IOrienteeringProblemData> OrienteeringProblemDataParameter { get; private set; }
+    [Storable] public OptionalValueParameter<OrienteeringSolution> BestKnownSolutionParameter { get; private set; }
+    [Storable] private IResultParameter<OrienteeringSolution> BestOrienteeringSolutionParameter { get; set; }
+    public IResultDefinition<OrienteeringSolution> BestOrienteeringSolution => BestOrienteeringSolutionParameter;
+
+    public IOrienteeringProblemData OrienteeringProblemData {
+      get { return OrienteeringProblemDataParameter.Value; }
+      set { OrienteeringProblemDataParameter.Value = value; }
+    }
+    public OrienteeringSolution BestKnownSolution {
       get { return BestKnownSolutionParameter.Value; }
       set { BestKnownSolutionParameter.Value = value; }
     }
-    private BestOrienteeringSolutionAnalyzer BestOrienteeringSolutionAnalyser {
-      get { return Operators.OfType<BestOrienteeringSolutionAnalyzer>().SingleOrDefault(); }
-    }
-    #endregion
 
     [StorableConstructor]
@@ -117,5 +62,7 @@
     private OrienteeringProblem(OrienteeringProblem original, Cloner cloner)
       : base(original, cloner) {
-      RegisterEventHandlers();
+      OrienteeringProblemDataParameter = cloner.Clone(original.OrienteeringProblemDataParameter);
+      BestKnownSolutionParameter = cloner.Clone(original.BestKnownSolutionParameter);
+      BestOrienteeringSolutionParameter = cloner.Clone(original.BestOrienteeringSolutionParameter);
     }
     public override IDeepCloneable Clone(Cloner cloner) {
@@ -123,154 +70,108 @@
     }
     public OrienteeringProblem()
-      : base(new OrienteeringEvaluator(), new GreedyOrienteeringTourCreator()) {
-      Parameters.Add(new OptionalValueParameter<DoubleMatrix>("Coordinates", "The x- and y-Coordinates of the points."));
-      Parameters.Add(new ValueParameter<DistanceMatrix>("DistanceMatrix", "The matrix which contains the distances between the points."));
-      Parameters.Add(new FixedValueParameter<IntValue>("StartingPoint", "Index of the starting point.", new IntValue(0)));
-      Parameters.Add(new FixedValueParameter<IntValue>("TerminalPoint", "Index of the ending point.", new IntValue(0)));
-      Parameters.Add(new FixedValueParameter<DoubleValue>("MaximumDistance", "The maximum distance constraint for a Orienteering solution."));
-      Parameters.Add(new ValueParameter<DoubleArray>("Scores", "The scores of the points."));
-      Parameters.Add(new FixedValueParameter<DoubleValue>("PointVisitingCosts", "The costs for visiting a point."));
-      Parameters.Add(new OptionalValueParameter<IntegerVector>("BestKnownSolution", "The best known solution of this Orienteering instance."));
-
-      Maximization.Value = true;
-      MaximizationParameter.Hidden = true;
-
-      SolutionCreator.IntegerVectorParameter.ActualName = "OrienteeringSolution";
-
-      InitializeInitialOrienteeringInstance();
-
-      ParameterizeSolutionCreator();
-      ParameterizeEvaluator();
+      : base(new IntegerVectorEncoding("Route")) {
+      Parameters.Add(OrienteeringProblemDataParameter = new ValueParameter<IOrienteeringProblemData>("OP Data", "The main parameters for the orienteering problem.", new OrienteeringProblemData()));
+      Parameters.Add(BestKnownSolutionParameter = new OptionalValueParameter<OrienteeringSolution>("BestKnownSolution", "The best known solution of this Orienteering instance."));
+      Parameters.Add(BestOrienteeringSolutionParameter = new ResultParameter<OrienteeringSolution>("Best Orienteering Solution", "The best so far solution found."));
+      Maximization = true;
 
       InitializeOperators();
-      RegisterEventHandlers();
-    }
-
-    #region Events
-    protected override void OnSolutionCreatorChanged() {
-      base.OnSolutionCreatorChanged();
-      SolutionCreator.IntegerVectorParameter.ActualNameChanged += SolutionCreator_IntegerVectorParameter_ActualNameChanged;
-      ParameterizeSolutionCreator();
-      ParameterizeEvaluator();
-      ParameterizeAnalyzer();
+    }
+
+    public override ISingleObjectiveEvaluationResult Evaluate(IntegerVector solution, IRandom random, CancellationToken cancellationToken) {
+      var data = OrienteeringProblemData;
+      var score = CalculateScore(data, solution);
+      var travelCosts = CalculateTravelCosts(data, solution);
+      var quality = CalculateQuality(data, score, travelCosts);
+
+      return new SingleObjectiveEvaluationResult(quality);
+    }
+
+    public static double CalculateQuality(IOrienteeringProblemData data, double score, double travelCosts) {
+      if (travelCosts > data.MaximumTravelCosts) return data.MaximumTravelCosts - travelCosts; // negative excessive distance
+      return score;
+    }
+    public static double CalculateScore(IOrienteeringProblemData data, IEnumerable<int> solution) {
+      return solution.Sum(t => data.GetScore(t));
+    }
+    public static double CalculateTravelCosts(IOrienteeringProblemData data, IntegerVector solution) {
+      var distance = data.RoutingData.GetPathDistance(solution, closed: false);
+      distance += (solution.Length - 2) * data.PointVisitingCosts;
+      return distance;
+    }
+    public static double CalculateTravelCosts(IOrienteeringProblemData data, IList<int> solution) {
+      var distance = data.RoutingData.GetPathDistance(solution, closed: false);
+      distance += (solution.Count - 2) * data.PointVisitingCosts;
+      return distance;
+    }
+
+    public override void Analyze(IntegerVector[] vectors, double[] qualities, ResultCollection results, IRandom random) {
+      base.Analyze(vectors, qualities, results, random);
+      var data = OrienteeringProblemData;
+
+      var best = GetBestSolution(vectors, qualities);
+      var score = CalculateScore(OrienteeringProblemData, best.Item1);
+      var travelCosts = CalculateTravelCosts(OrienteeringProblemData, best.Item1);
+      var quality = CalculateQuality(OrienteeringProblemData, score, travelCosts);
+
+      if (BestKnownQuality == double.NaN || best.Item2 > BestKnownQuality) {
+        BestKnownQuality = best.Item2;
+        BestKnownSolutionParameter.ActualValue = data.GetSolution((IntegerVector)best.Item1.Clone(), quality, score, travelCosts);
+      }
+
+      var bestSoFar = BestOrienteeringSolutionParameter.ActualValue;
+      
+      if (bestSoFar == null) {
+        bestSoFar = data.GetSolution((IntegerVector)best.Item1.Clone(), quality, score, travelCosts);
+        BestOrienteeringSolutionParameter.ActualValue = bestSoFar;
+      } else {
+        if (IsBetter(best.Item2, bestSoFar.Quality.Value)) {
+          bestSoFar.Route = (IntegerVector)best.Item1.Clone();
+          bestSoFar.Quality.Value = quality;
+          bestSoFar.Score.Value = score;
+          bestSoFar.TravelCosts.Value = travelCosts;
+        }
+      }
+    }
+    public static double CalculateInsertionCosts(IOrienteeringProblemData data, IList<int> path, int insertPosition, int point) {
+      double detour = data.RoutingData.GetDistance(path[insertPosition - 1], point) + data.RoutingData.GetDistance(point, path[insertPosition]);
+      detour += data.PointVisitingCosts;
+      detour -= data.RoutingData.GetDistance(path[insertPosition - 1], path[insertPosition]);
+      return detour;
+    }
+    public static double CalculateReplacementCosts(IOrienteeringProblemData data, IList<int> path, int replacePosition, int point) {
+      double detour = data.RoutingData.GetDistance(path[replacePosition - 1], point) + data.RoutingData.GetDistance(point, path[replacePosition + 1]);
+      detour -= data.RoutingData.GetDistance(path[replacePosition - 1], path[replacePosition]) + data.RoutingData.GetDistance(path[replacePosition], path[replacePosition + 1]);
+      return detour;
+    }
+    public static double CalculateRemovementSaving(IOrienteeringProblemData data, IList<int> path, int removePosition) {
+      double saving = data.RoutingData.GetDistance(path[removePosition - 1], path[removePosition]);
+      saving += data.RoutingData.GetDistance(path[removePosition], path[removePosition + 1]);
+      saving -= data.RoutingData.GetDistance(path[removePosition - 1], path[removePosition + 1]);
+      saving += data.PointVisitingCosts;
+      return saving;
+    }
+
+    protected override void OnEncodingChanged() {
+      base.OnEncodingChanged();
       ParameterizeOperators();
     }
+
     protected override void OnEvaluatorChanged() {
       base.OnEvaluatorChanged();
-      ParameterizeEvaluator();
-      ParameterizeAnalyzer();
-    }
-    private void SolutionCreator_IntegerVectorParameter_ActualNameChanged(object sender, EventArgs e) {
-      ParameterizeEvaluator();
-      ParameterizeAnalyzer();
       ParameterizeOperators();
     }
-    private void CoordinatesParameter_ValueChanged(object sender, EventArgs e) {
-      if (Coordinates != null) {
-        Coordinates.ItemChanged += new EventHandler<EventArgs<int, int>>(CoordinatesValue_ItemChanged);
-        Coordinates.Reset += new EventHandler(CoordinatesValue_Reset);
-      }
-      ParameterizeSolutionCreator();
-      UpdateDistanceMatrix();
-      CheckStartingIndex();
-      CheckTerminalIndex();
-    }
-    private void CoordinatesValue_ItemChanged(object sender, EventArgs<int, int> e) {
-      UpdateDistanceMatrix();
-      CheckStartingIndex();
-      CheckTerminalIndex();
-    }
-    private void CoordinatesValue_Reset(object sender, EventArgs e) {
-      ParameterizeSolutionCreator();
-      UpdateDistanceMatrix();
-      CheckStartingIndex();
-      CheckTerminalIndex();
-    }
-    private void StartingPointParameterValue_ValueChanged(object sender, EventArgs e) {
-      CheckStartingIndex();
-    }
-
-    private void TerminalPointParameterValue_ValueChanged(object sender, EventArgs e) {
-      CheckTerminalIndex();
-    }
-    private void MaximumDistanceParameterValue_ValueChanged(object sender, EventArgs e) { }
-    private void ScoresParameter_ValueChanged(object sender, EventArgs e) {
-      ParameterizeEvaluator();
-      ParameterizeAnalyzer();
-      ParameterizeSolutionCreator();
-
-      ScoresParameter.Value.Reset += new EventHandler(ScoresValue_Reset);
-    }
-    private void ScoresValue_Reset(object sender, EventArgs e) {
-      ParameterizeSolutionCreator();
-    }
-    private void PointVisitingCostsParameterValue_ValueChanged(object sender, EventArgs e) { }
-
-    private void BestKnownSolutionParameter_ValueChanged(object sender, EventArgs e) {
-      if (BestKnownSolution == null)
-        BestKnownQuality = null;
-    }
-    #endregion
-
-    #region Helpers
-    [StorableHook(HookType.AfterDeserialization)]
-    private void AfterDeserialization() {
-      RegisterEventHandlers();
-    }
-
-    private void RegisterEventHandlers() {
-      SolutionCreator.IntegerVectorParameter.ActualNameChanged += SolutionCreator_IntegerVectorParameter_ActualNameChanged;
-
-      CoordinatesParameter.ValueChanged += CoordinatesParameter_ValueChanged;
-      if (CoordinatesParameter.Value != null) {
-        CoordinatesParameter.Value.ItemChanged += CoordinatesValue_ItemChanged;
-        CoordinatesParameter.Value.Reset += CoordinatesValue_Reset;
-      }
-
-      StartingPointParameter.Value.ValueChanged += StartingPointParameterValue_ValueChanged;
-      TerminalPointParameter.Value.ValueChanged += TerminalPointParameterValue_ValueChanged;
-      MaximumDistanceParameter.Value.ValueChanged += MaximumDistanceParameterValue_ValueChanged;
-      PointVisitingCostsParameter.Value.ValueChanged += PointVisitingCostsParameterValue_ValueChanged;
-
-      ScoresParameter.ValueChanged += ScoresParameter_ValueChanged;
-      ScoresParameter.Value.Reset += ScoresValue_Reset;
-
-      BestKnownSolutionParameter.ValueChanged += BestKnownSolutionParameter_ValueChanged;
-    }
-
-    private void ParameterizeSolutionCreator() {
-      SolutionCreator.DistanceMatrixParameter.ActualName = DistanceMatrixParameter.Name;
-      SolutionCreator.ScoresParameter.ActualName = ScoresParameter.Name;
-      SolutionCreator.MaximumDistanceParameter.ActualName = MaximumDistanceParameter.Name;
-      SolutionCreator.StartingPointParameter.ActualName = StartingPointParameter.Name;
-      SolutionCreator.TerminalPointParameter.ActualName = TerminalPointParameter.Name;
-      SolutionCreator.PointVisitingCostsParameter.ActualName = PointVisitingCostsParameter.Name;
-    }
-    private void ParameterizeEvaluator() {
-      Evaluator.IntegerVectorParameter.ActualName = SolutionCreator.IntegerVectorParameter.ActualName;
-      Evaluator.ScoresParameter.ActualName = ScoresParameter.Name;
-      Evaluator.DistanceMatrixParameter.ActualName = DistanceMatrixParameter.Name;
-      Evaluator.MaximumDistanceParameter.ActualName = MaximumDistanceParameter.Name;
-      Evaluator.PointVisitingCostsParameter.ActualName = PointVisitingCostsParameter.Name;
-    }
-    private void ParameterizeAnalyzer() {
-      if (BestOrienteeringSolutionAnalyser != null) {
-        BestOrienteeringSolutionAnalyser.QualityParameter.ActualName = Evaluator.QualityParameter.ActualName;
-
-        BestOrienteeringSolutionAnalyser.IntegerVector.ActualName = SolutionCreator.IntegerVectorParameter.ActualName;
-        BestOrienteeringSolutionAnalyser.CoordinatesParameter.ActualName = CoordinatesParameter.Name;
-        BestOrienteeringSolutionAnalyser.ScoresParameter.ActualName = ScoresParameter.Name;
-
-        BestOrienteeringSolutionAnalyser.ResultsParameter.ActualName = "Results";
-        BestOrienteeringSolutionAnalyser.BestKnownQualityParameter.ActualName = BestKnownQualityParameter.Name;
-        BestOrienteeringSolutionAnalyser.BestKnownSolutionParameter.ActualName = BestKnownSolutionParameter.Name;
-      }
-    }
+
     private void InitializeOperators() {
-      Operators.Add(new BestOrienteeringSolutionAnalyzer());
-      ParameterizeAnalyzer();
-
-      Operators.Add(new OrienteeringLocalImprovementOperator());
-      Operators.Add(new OrienteeringShakingOperator());
+      Encoding.SolutionCreator = new GreedyOrienteeringTourCreator() {
+        OrienteeringProblemDataParameter = { ActualName = OrienteeringProblemDataParameter.Name }
+      };
+
+      Operators.Add(new OrienteeringLocalImprovementOperator() {
+        OrienteeringProblemDataParameter = { ActualName = OrienteeringProblemDataParameter.Name }
+      });
+      Operators.Add(new OrienteeringShakingOperator() {
+        OrienteeringProblemDataParameter = { ActualName = OrienteeringProblemDataParameter.Name }
+      });
       Operators.Add(new QualitySimilarityCalculator());
       Operators.Add(new PopulationSimilarityAnalyzer(Operators.OfType<ISolutionSimilarityCalculator>()));
@@ -278,81 +179,17 @@
       ParameterizeOperators();
     }
+
     private void ParameterizeOperators() {
       foreach (var op in Operators.OfType<OrienteeringLocalImprovementOperator>()) {
-        op.IntegerVectorParameter.ActualName = SolutionCreator.IntegerVectorParameter.ActualName;
-        op.DistanceMatrixParameter.ActualName = DistanceMatrixParameter.Name;
-        op.ScoresParameter.ActualName = ScoresParameter.Name;
-        op.MaximumDistanceParameter.ActualName = MaximumDistanceParameter.Name;
-        op.StartingPointParameter.ActualName = StartingPointParameter.Name;
-        op.TerminalPointParameter.ActualName = TerminalPointParameter.Name;
-        op.PointVisitingCostsParameter.ActualName = PointVisitingCostsParameter.Name;
+        op.IntegerVectorParameter.ActualName = Encoding.Name;
+        op.QualityParameter.ActualName = Evaluator.QualityParameter.ActualName;
       }
       foreach (var op in Operators.OfType<OrienteeringShakingOperator>()) {
-        op.IntegerVectorParameter.ActualName = SolutionCreator.IntegerVectorParameter.ActualName;
-        op.DistanceMatrixParameter.ActualName = DistanceMatrixParameter.Name;
-        op.ScoresParameter.ActualName = ScoresParameter.Name;
-        op.MaximumDistanceParameter.ActualName = MaximumDistanceParameter.Name;
-        op.StartingPointParameter.ActualName = StartingPointParameter.Name;
-        op.TerminalPointParameter.ActualName = TerminalPointParameter.Name;
-        op.PointVisitingCostsParameter.ActualName = PointVisitingCostsParameter.Name;
+        op.IntegerVectorParameter.ActualName = Encoding.Name;
       }
       foreach (var similarityCalculator in Operators.OfType<ISolutionSimilarityCalculator>()) {
-        similarityCalculator.SolutionVariableName = SolutionCreator.IntegerVectorParameter.ActualName;
+        similarityCalculator.SolutionVariableName = Encoding.Name;
         similarityCalculator.QualityVariableName = Evaluator.QualityParameter.ActualName;
       }
-    }
-    #endregion
-
-    private DistanceMatrix CalculateDistanceMatrix(double[,] coordinates) {
-      var distances = DistanceHelper.GetDistanceMatrix(DistanceMeasure.Euclidean, coordinates, null, coordinates.GetLength(0));
-
-      return new DistanceMatrix(distances);
-    }
-    private void UpdateDistanceMatrix() {
-      if (Coordinates == null) {
-        DistanceMatrix = new DistanceMatrix(0, 0);
-        return;
-      }
-
-      var coordinates = Coordinates;
-      int dimension = coordinates.Rows;
-      var distances = new double[dimension, dimension];
-      for (int i = 0; i < dimension - 1; i++) {
-        for (int j = i + 1; j < dimension; j++) {
-          double x1 = coordinates[i, 0];
-          double y1 = coordinates[i, 1];
-          double x2 = coordinates[j, 0];
-          double y2 = coordinates[j, 1];
-          distances[i, j] = Math.Sqrt((x1 - x2) * (x1 - x2) + (y1 - y2) * (y1 - y2));
-          distances[j, i] = distances[i, j];
-        }
-      }
-      DistanceMatrix = new DistanceMatrix(distances);
-    }
-    private void CheckStartingIndex() {
-      if (StartingPoint < 0) StartingPoint = 0;
-      if (StartingPoint >= DistanceMatrix.Rows) StartingPoint = DistanceMatrix.Rows - 1;
-    }
-    private void CheckTerminalIndex() {
-      if (TerminalPoint < 0) TerminalPoint = 0;
-      if (TerminalPoint >= DistanceMatrix.Rows) TerminalPoint = DistanceMatrix.Rows - 1;
-    }
-
-    private void InitializeInitialOrienteeringInstance() {
-      var coordinates = new double[21, 2] {
-        {  4.60,  7.10 }, {  5.70, 11.40 }, {  4.40, 12.30 }, {  2.80, 14.30 }, {  3.20, 10.30 },
-        {  3.50,  9.80 }, {  4.40,  8.40 }, {  7.80, 11.00 }, {  8.80,  9.80 }, {  7.70,  8.20 },
-        {  6.30,  7.90 }, {  5.40,  8.20 }, {  5.80,  6.80 }, {  6.70,  5.80 }, { 13.80, 13.10 },
-        { 14.10, 14.20 }, { 11.20, 13.60 }, {  9.70, 16.40 }, {  9.50, 18.80 }, {  4.70, 16.80 },
-        {  5.00,  5.60 }
-      };
-      Coordinates = new DoubleMatrix(coordinates);
-      DistanceMatrix = CalculateDistanceMatrix(coordinates);
-
-      StartingPoint = 0;
-      TerminalPoint = 20;
-      MaximumDistance = 30;
-
-      Scores = new DoubleArray(new double[21] { 0, 20, 20, 30, 15, 15, 10, 20, 20, 20, 15, 10, 10, 25, 40, 40, 30, 30, 50, 30, 0 });
     }
 
@@ -370,16 +207,6 @@
       Description = data.Description;
 
-      Coordinates = data.Coordinates != null ? new DoubleMatrix(data.Coordinates) : null;
-      if (data.Distances != null)
-        DistanceMatrix = new DistanceMatrix(data.Distances);
-      else
-        DistanceMatrix = new DistanceMatrix(data.GetDistanceMatrix());
-
-      StartingPoint = data.StartingPoint;
-      TerminalPoint = data.TerminalPoint;
-
-      PointVisitingCosts = data.PointVisitingCosts;
-      MaximumDistance = data.MaximumDistance;
-      Scores = new DoubleArray(data.Scores);
+      var tsp = data.Coordinates != null ? (ITSPData)new EuclideanTSPData(Name, data.Coordinates) : new MatrixTSPData(Name, data.Distances ?? data.GetDistanceMatrix(), data.Coordinates);
+      OrienteeringProblemData = new OrienteeringProblemData(tsp, data.StartingPoint, data.TerminalPoint, data.Scores, data.MaximumDistance, data.PointVisitingCosts);
     }
 
@@ -396,16 +223,14 @@
       Description = data.Description;
 
-      Coordinates = data.Coordinates != null ? new DoubleMatrix(data.Coordinates) : null;
-      if (data.Distances != null)
-        DistanceMatrix = new DistanceMatrix(data.Distances);
-      else
-        DistanceMatrix = new DistanceMatrix(data.GetDistanceMatrix());
-
-      StartingPoint = 0; // First city is interpreted as start point
-      TerminalPoint = data.Dimension - 1; // Last city is interpreted als end point
-
-      PointVisitingCosts = 0;
-      MaximumDistance = DistanceMatrix.Average() * 5.0; // distance from start to end first to last city is interpreted as maximum distance
-      Scores = new DoubleArray(Enumerable.Repeat(1.0, data.Dimension).ToArray()); // all scores are 1
+
+      var tsp = data.Coordinates != null ? (ITSPData)new EuclideanTSPData(Name, data.Coordinates) : new MatrixTSPData(Name, data.Distances ?? data.GetDistanceMatrix(), data.Coordinates);
+      var avgDist = 0.0;
+      for (var i = 0; i < data.Dimension - 1; i++)
+        for (var j = i + 1; i < data.Dimension; j++)
+          avgDist += tsp.GetDistance(i, j);
+      avgDist /= (data.Dimension - 1) * data.Dimension / 2.0;
+
+      OrienteeringProblemData = new OrienteeringProblemData(tsp, 0, data.Dimension - 1,
+        Enumerable.Repeat(1.0, data.Dimension).ToArray(), 5 * avgDist, 0);
     }
 
@@ -422,15 +247,8 @@
       Description = data.Description;
 
-      Coordinates = data.Coordinates != null ? new DoubleMatrix(data.Coordinates) : null;
-      DistanceMatrix = data.Distances != null
-        ? new DistanceMatrix(data.Distances)
-        : CalculateDistanceMatrix(data.Coordinates);
-
-      StartingPoint = 0; // Depot is interpreted as start point
-      TerminalPoint = 0; // Depot is interpreted als end point
-
-      PointVisitingCosts = 0;
-      MaximumDistance = data.Capacity * 2; // capacity is interpreted as max distance
-      Scores = new DoubleArray(data.Demands); // demands are interpreted as scores
+      var tsp = data.Coordinates != null ? (ITSPData)new EuclideanTSPData(Name, data.Coordinates) : new MatrixTSPData(Name, data.Distances ?? data.GetDistanceMatrix(), data.Coordinates);
+
+      OrienteeringProblemData = new OrienteeringProblemData(tsp, 0, 0,
+        data.Demands, data.Capacity * 2, 0);
     }
     #endregion
Index: /branches/2521_ProblemRefactoring/HeuristicLab.Problems.Orienteering/3.3/OrienteeringProblemdata.cs
===================================================================
--- /branches/2521_ProblemRefactoring/HeuristicLab.Problems.Orienteering/3.3/OrienteeringProblemdata.cs	(revision 17525)
+++ /branches/2521_ProblemRefactoring/HeuristicLab.Problems.Orienteering/3.3/OrienteeringProblemdata.cs	(revision 17525)
@@ -0,0 +1,105 @@
+﻿using System;
+using System.Linq;
+using HEAL.Attic;
+using HeuristicLab.Common;
+using HeuristicLab.Core;
+using HeuristicLab.Data;
+using HeuristicLab.Encodings.IntegerVectorEncoding;
+using HeuristicLab.Problems.Instances.Types;
+using HeuristicLab.Problems.TravelingSalesman;
+
+namespace HeuristicLab.Problems.Orienteering {
+  [StorableType("dd2d0ecc-372e-46f1-846f-fb4ca2afa124")]
+  public interface IOrienteeringProblemData : INamedItem {
+    ITSPData RoutingData { get; }
+    int StartingPoint { get; }
+    int TerminalPoint { get; }
+    double MaximumTravelCosts { get; }
+    double PointVisitingCosts { get; }
+
+    double GetScore(int city);
+    OrienteeringSolution GetSolution(IntegerVector route, double quality, double score, double travelCosts);
+    OPData Export();
+  }
+
+  [Item("Orienteering Problem Data", "Represents the main data for an orienteering problem.")]
+  [StorableType("d7d2d61a-7d51-4254-ab68-375942106058")]
+  public class OrienteeringProblemData : NamedItem, IOrienteeringProblemData {
+    [Storable] public ITSPData RoutingData { get; protected set; }
+    [Storable] public int StartingPoint { get; protected set; }
+    [Storable] public int TerminalPoint { get; protected set; }
+    [Storable] public DoubleArray Scores { get; protected set; }
+    [Storable] public double MaximumTravelCosts { get; protected set; }
+    [Storable] public double PointVisitingCosts { get; protected set; }
+
+    [StorableConstructor]
+    protected OrienteeringProblemData(StorableConstructorFlag _) : base(_) { }
+    protected OrienteeringProblemData(OrienteeringProblemData original, Cloner cloner) : base(original, cloner) {
+      RoutingData = original.RoutingData;
+      StartingPoint = original.StartingPoint;
+      TerminalPoint = original.TerminalPoint;
+      Scores = original.Scores;
+      MaximumTravelCosts = original.MaximumTravelCosts;
+      PointVisitingCosts = original.PointVisitingCosts;
+    }
+    public OrienteeringProblemData() {
+      RoutingData = new EuclideanTSPData("HL OP Default", defaultCoordinates);
+      Name = RoutingData.Name;
+      StartingPoint = 0;
+      TerminalPoint = 20;
+      Scores = new DoubleArray(Enumerable.Repeat(1.0, RoutingData.Cities).ToArray(), @readonly: true);
+      MaximumTravelCosts = 30;
+      PointVisitingCosts = 0;
+    }
+    public OrienteeringProblemData(ITSPData tspData, int startingPoint, int terminalPoint, double[] scores, double maxDist, double pointVisitCosts)
+      : this(tspData, startingPoint, terminalPoint, new DoubleArray(scores, @readonly: true), maxDist, pointVisitCosts) { }
+    public OrienteeringProblemData(ITSPData tspData, int startingPoint, int terminalPoint, DoubleArray scores, double maxDist, double pointVisitCosts)
+      : base(tspData.Name, tspData.Description) {
+      if (tspData.Cities != scores.Length) throw new ArgumentException("Unequal number of cities and scores.");
+      if (startingPoint < 0 || startingPoint >= tspData.Cities) throw new ArgumentException("Starting point is not in the range of cities.", "startingPoint");
+      if (terminalPoint < 0 || terminalPoint >= tspData.Cities) throw new ArgumentException("Starting point is not in the range of cities.", "startingPoint");
+      RoutingData = tspData;
+      StartingPoint = startingPoint;
+      TerminalPoint = terminalPoint;
+      Scores = scores.AsReadOnly();
+      MaximumTravelCosts = maxDist;
+      PointVisitingCosts = pointVisitCosts;
+    }
+
+    public override IDeepCloneable Clone(Cloner cloner) {
+      return new OrienteeringProblemData(this, cloner);
+    }
+
+    public double GetScore(int site) => Scores[site];
+
+    public OrienteeringSolution GetSolution(IntegerVector route, double quality, double score, double travelCosts) {
+      return new OrienteeringSolution(route, this, quality, score, travelCosts);
+    }
+
+    public OPData Export() {
+      var tspExport = RoutingData.Export();
+      return new OPData() {
+        Name = tspExport.Name,
+        Description = tspExport.Description,
+        Coordinates = tspExport.Coordinates,
+        Dimension = tspExport.Dimension,
+        DistanceMeasure = tspExport.DistanceMeasure,
+        Distances = tspExport.Distances,
+        MaximumDistance = MaximumTravelCosts,
+        Scores = Scores.CloneAsArray(),
+        StartingPoint = StartingPoint,
+        TerminalPoint = TerminalPoint,
+        PointVisitingCosts = PointVisitingCosts
+      };
+    }
+
+    private static double[,] defaultCoordinates = new double[21, 2] {
+      {  4.60,  7.10 }, {  5.70, 11.40 }, {  4.40, 12.30 }, {  2.80, 14.30 }, {  3.20, 10.30 },
+      {  3.50,  9.80 }, {  4.40,  8.40 }, {  7.80, 11.00 }, {  8.80,  9.80 }, {  7.70,  8.20 },
+      {  6.30,  7.90 }, {  5.40,  8.20 }, {  5.80,  6.80 }, {  6.70,  5.80 }, { 13.80, 13.10 },
+      { 14.10, 14.20 }, { 11.20, 13.60 }, {  9.70, 16.40 }, {  9.50, 18.80 }, {  4.70, 16.80 },
+      {  5.00,  5.60 }
+    };
+    private static double[] defaultScores = new double[21] { 0, 20, 20, 30, 15, 15, 10, 20, 20, 20, 15, 10, 10, 25, 40, 40, 30, 30, 50, 30, 0 };
+  }
+}
Index: /branches/2521_ProblemRefactoring/HeuristicLab.Problems.Orienteering/3.3/OrienteeringSolution.cs
===================================================================
--- /branches/2521_ProblemRefactoring/HeuristicLab.Problems.Orienteering/3.3/OrienteeringSolution.cs	(revision 17524)
+++ /branches/2521_ProblemRefactoring/HeuristicLab.Problems.Orienteering/3.3/OrienteeringSolution.cs	(revision 17525)
@@ -20,83 +20,42 @@
 #endregion
 
-using System;
+using System.ComponentModel;
 using System.Drawing;
+using HEAL.Attic;
 using HeuristicLab.Common;
 using HeuristicLab.Core;
 using HeuristicLab.Data;
 using HeuristicLab.Encodings.IntegerVectorEncoding;
-using HEAL.Attic;
+using HeuristicLab.Encodings.PermutationEncoding;
+using HeuristicLab.Problems.TravelingSalesman;
 
 namespace HeuristicLab.Problems.Orienteering {
   [Item("OrienteeringSolution", "Represents a Orienteering solution which can be visualized in the GUI.")]
   [StorableType("BC58ED08-B9A7-40F3-B8E0-A6B33AA993F4")]
-  public sealed class OrienteeringSolution : Item {
+  public sealed class OrienteeringSolution : Item, ITSPSolution {
     public static new Image StaticItemImage {
       get { return HeuristicLab.Common.Resources.VSImageLibrary.Image; }
     }
 
-    [Storable]
-    private IntegerVector integerVector;
-    public IntegerVector IntegerVector {
-      get { return integerVector; }
+    [Storable] private Permutation routeAsPermutation;
+    [Storable] private IntegerVector route;
+    public IntegerVector Route {
+      get { return route; }
       set {
-        if (integerVector != value) {
-          if (integerVector != null) DeregisterIntegerVectorEvents();
-          integerVector = value;
-          if (integerVector != null) RegisterIntegerVectorEvents();
-          OnIntegerVectorChanged();
-        }
+        if (route == value) return;
+        route = value;
+        routeAsPermutation = new Permutation(PermutationTypes.RelativeDirected, value);
+        OnPropertyChanged(nameof(Route));
+        OnPropertyChanged(nameof(ITSPSolution.Tour));
       }
     }
-    [Storable]
-    private DoubleMatrix coordinates;
-    public DoubleMatrix Coordinates {
-      get { return coordinates; }
+    [Storable] private IOrienteeringProblemData opData;
+    public IOrienteeringProblemData OPData {
+      get { return opData; }
       set {
-        if (coordinates != value) {
-          if (coordinates != null) DeregisterCoordinatesEvents();
-          coordinates = value;
-          if (coordinates != null) RegisterCoordinatesEvents();
-          OnCoordinatesChanged();
-        }
-      }
-    }
-    [Storable]
-    private IntValue startingPoint;
-    public IntValue StartingPoint {
-      get { return startingPoint; }
-      set {
-        if (startingPoint != value) {
-          if (startingPoint != null) DeregisterStartingPointEvents();
-          startingPoint = value;
-          if (startingPoint != null) RegisterStartingPointEvents();
-          OnStartingPointChanged();
-        }
-      }
-    }
-    [Storable]
-    private IntValue terminalPoint;
-    public IntValue TerminalPoint {
-      get { return terminalPoint; }
-      set {
-        if (terminalPoint != value) {
-          if (terminalPoint != null) DeregisterTerminalPointEvents();
-          terminalPoint = value;
-          if (terminalPoint != null) RegisterTerminalPointEvents();
-          OnTerminalPointChanged();
-        }
-      }
-    }
-    [Storable]
-    private DoubleArray scores;
-    public DoubleArray Scores {
-      get { return scores; }
-      set {
-        if (scores != value) {
-          if (scores != null) DeregisterScoresEvents();
-          scores = value;
-          if (scores != null) RegisterScoresEvents();
-          OnScoresChanged();
-        }
+        if (opData == value) return;
+        opData = value;
+        OnPropertyChanged(nameof(OPData));
+        OnPropertyChanged(nameof(ITSPSolution.TSPData));
       }
     }
@@ -106,38 +65,34 @@
       get { return quality; }
       set {
-        if (quality != value) {
-          if (quality != null) DeregisterQualityEvents();
-          quality = value;
-          if (quality != null) RegisterQualityEvents();
-          OnQualityChanged();
-        }
+        if (quality == value) return;
+        quality = value;
+        OnPropertyChanged(nameof(Quality));
       }
     }
     [Storable]
-    private DoubleValue penalty;
-    public DoubleValue Penalty {
-      get { return penalty; }
+    private DoubleValue score;
+    public DoubleValue Score {
+      get { return score; }
       set {
-        if (penalty != value) {
-          if (penalty != null) DeregisterPenaltyEvents();
-          penalty = value;
-          if (penalty != null) RegisterPenaltyEvents();
-          OnPenaltyChanged();
-        }
+        if (score == value) return;
+        score = value;
+        OnPropertyChanged(nameof(Score));
       }
     }
     [Storable]
-    private DoubleValue distance;
-    public DoubleValue Distance {
-      get { return distance; }
+    private DoubleValue travelCosts;
+    public DoubleValue TravelCosts {
+      get { return travelCosts; }
       set {
-        if (distance != value) {
-          if (distance != null) DeregisterDistanceEvents();
-          distance = value;
-          if (distance != null) RegisterDistanceEvents();
-          OnDistanceChanged();
-        }
+        if (travelCosts == value) return;
+        travelCosts = value;
+        OnPropertyChanged(nameof(TravelCosts));
+        OnPropertyChanged(nameof(ITSPSolution.TourLength));
       }
     }
+
+    ITSPData ITSPSolution.TSPData => OPData.RoutingData;
+    Permutation ITSPSolution.Tour => routeAsPermutation;
+    DoubleValue ITSPSolution.TourLength => TravelCosts;
 
     [StorableConstructor]
@@ -145,22 +100,18 @@
     private OrienteeringSolution(OrienteeringSolution original, Cloner cloner)
       : base(original, cloner) {
-      this.integerVector = cloner.Clone(original.integerVector);
-      this.coordinates = cloner.Clone(original.coordinates);
+      this.route = cloner.Clone(original.route);
+      this.opData = cloner.Clone(original.opData);
       this.quality = cloner.Clone(original.quality);
-      this.penalty = cloner.Clone(original.penalty);
-      Initialize();
+      this.score = cloner.Clone(original.score);
     }
-    public OrienteeringSolution(IntegerVector integerVector, DoubleMatrix coordinates, IntValue startingPoint, IntValue terminalPoint,
-      DoubleArray scores, DoubleValue quality = null, DoubleValue penalty = null, DoubleValue distance = null)
+    public OrienteeringSolution(IntegerVector route, IOrienteeringProblemData opData, double quality, double score, double travelCosts)
+      : this(route, opData, new DoubleValue(quality), new DoubleValue(score), new DoubleValue(travelCosts)) { }
+    public OrienteeringSolution(IntegerVector route, IOrienteeringProblemData opData, DoubleValue quality = null, DoubleValue score = null, DoubleValue distance = null)
       : base() {
-      this.integerVector = integerVector;
-      this.coordinates = coordinates;
-      this.startingPoint = startingPoint;
-      this.terminalPoint = terminalPoint;
-      this.scores = scores;
+      this.route = route;
+      this.opData = opData;
       this.quality = quality;
-      this.penalty = penalty;
-      this.distance = distance;
-      Initialize();
+      this.score = score;
+      this.travelCosts = distance;
     }
 
@@ -169,166 +120,8 @@
     }
 
-    [StorableHook(HookType.AfterDeserialization)]
-    private void AfterDeserialization() {
-      Initialize();
+    public event PropertyChangedEventHandler PropertyChanged;
+    private void OnPropertyChanged(string property) {
+      PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(property));
     }
-
-    private void Initialize() {
-      if (integerVector != null) RegisterIntegerVectorEvents();
-      if (coordinates != null) RegisterCoordinatesEvents();
-      if (startingPoint != null) RegisterStartingPointEvents();
-      if (terminalPoint != null) RegisterTerminalPointEvents();
-      if (scores != null) RegisterScoresEvents();
-      if (quality != null) RegisterQualityEvents();
-      if (penalty != null) RegisterPenaltyEvents();
-      if (distance != null) RegisterDistanceEvents();
-    }
-
-    #region Events
-    public event EventHandler IntegerVectorChanged;
-    private void OnIntegerVectorChanged() {
-      var changed = IntegerVectorChanged;
-      if (changed != null)
-        changed(this, EventArgs.Empty);
-    }
-
-    public event EventHandler CoordinatesChanged;
-    private void OnCoordinatesChanged() {
-      var changed = CoordinatesChanged;
-      if (changed != null)
-        changed(this, EventArgs.Empty);
-    }
-
-    public event EventHandler StartingPointChanged;
-    private void OnStartingPointChanged() {
-      var changed = StartingPointChanged;
-      if (changed != null)
-        changed(this, EventArgs.Empty);
-    }
-
-    public event EventHandler TerminalPointChanged;
-    private void OnTerminalPointChanged() {
-      var changed = TerminalPointChanged;
-      if (changed != null)
-        changed(this, EventArgs.Empty);
-    }
-
-    public event EventHandler ScoresChanged;
-    private void OnScoresChanged() {
-      var changed = ScoresChanged;
-      if (changed != null)
-        changed(this, EventArgs.Empty);
-    }
-
-    public event EventHandler QualityChanged;
-    private void OnQualityChanged() {
-      var changed = QualityChanged;
-      if (changed != null)
-        changed(this, EventArgs.Empty);
-    }
-
-    public event EventHandler PenaltyChanged;
-    private void OnPenaltyChanged() {
-      var changed = PenaltyChanged;
-      if (changed != null)
-        changed(this, EventArgs.Empty);
-    }
-
-    public event EventHandler DistanceChanged;
-    private void OnDistanceChanged() {
-      var changed = DistanceChanged;
-      if (changed != null)
-        changed(this, EventArgs.Empty);
-    }
-
-    private void RegisterIntegerVectorEvents() {
-      IntegerVector.ItemChanged += new EventHandler<EventArgs<int>>(IntegerVector_ItemChanged);
-      IntegerVector.Reset += new EventHandler(IntegerVector_Reset);
-    }
-    private void DeregisterIntegerVectorEvents() {
-      IntegerVector.ItemChanged -= new EventHandler<EventArgs<int>>(IntegerVector_ItemChanged);
-      IntegerVector.Reset -= new EventHandler(IntegerVector_Reset);
-    }
-    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 RegisterStartingPointEvents() {
-      StartingPoint.ValueChanged += new EventHandler(StartingPoint_ValueChanged);
-    }
-    private void DeregisterStartingPointEvents() {
-      StartingPoint.ValueChanged -= new EventHandler(StartingPoint_ValueChanged);
-    }
-    private void RegisterTerminalPointEvents() {
-      TerminalPoint.ValueChanged += new EventHandler(TerminalPoint_ValueChanged);
-    }
-    private void DeregisterTerminalPointEvents() {
-      TerminalPoint.ValueChanged -= new EventHandler(TerminalPoint_ValueChanged);
-    }
-    private void RegisterScoresEvents() {
-      Scores.ItemChanged += new EventHandler<EventArgs<int>>(Scores_ItemChanged);
-      Scores.Reset += new EventHandler(Scores_Reset);
-    }
-    private void DeregisterScoresEvents() {
-      Scores.ItemChanged -= new EventHandler<EventArgs<int>>(Scores_ItemChanged);
-      Scores.Reset -= new EventHandler(Scores_Reset);
-    }
-    private void RegisterQualityEvents() {
-      Quality.ValueChanged += new EventHandler(Quality_ValueChanged);
-    }
-    private void DeregisterQualityEvents() {
-      Quality.ValueChanged -= new EventHandler(Quality_ValueChanged);
-    }
-    private void RegisterPenaltyEvents() {
-      Penalty.ValueChanged += new EventHandler(Penalty_ValueChanged);
-    }
-    private void DeregisterPenaltyEvents() {
-      Penalty.ValueChanged -= new EventHandler(Penalty_ValueChanged);
-    }
-    private void RegisterDistanceEvents() {
-      Distance.ValueChanged += new EventHandler(Distance_ValueChanged);
-    }
-    private void DeregisterDistanceEvents() {
-      Distance.ValueChanged -= new EventHandler(Distance_ValueChanged);
-    }
-
-    private void IntegerVector_ItemChanged(object sender, EventArgs<int> e) {
-      OnIntegerVectorChanged();
-    }
-    private void IntegerVector_Reset(object sender, EventArgs e) {
-      OnIntegerVectorChanged();
-    }
-    private void Coordinates_ItemChanged(object sender, EventArgs<int, int> e) {
-      OnCoordinatesChanged();
-    }
-    private void Coordinates_Reset(object sender, EventArgs e) {
-      OnCoordinatesChanged();
-    }
-    private void StartingPoint_ValueChanged(object sender, EventArgs e) {
-      OnStartingPointChanged();
-    }
-    private void TerminalPoint_ValueChanged(object sender, EventArgs e) {
-      OnTerminalPointChanged();
-    }
-    private void Scores_ItemChanged(object sender, EventArgs<int> e) {
-      OnCoordinatesChanged();
-    }
-    private void Scores_Reset(object sender, EventArgs e) {
-      OnCoordinatesChanged();
-    }
-    private void Quality_ValueChanged(object sender, EventArgs e) {
-      OnQualityChanged();
-    }
-    private void Penalty_ValueChanged(object sender, EventArgs e) {
-      OnPenaltyChanged();
-    }
-    private void Distance_ValueChanged(object sender, EventArgs e) {
-      OnDistanceChanged();
-    }
-    #endregion
   }
 }
Index: /branches/2521_ProblemRefactoring/HeuristicLab.Problems.Orienteering/3.3/Shakers/OrienteeringShakingOperator.cs
===================================================================
--- /branches/2521_ProblemRefactoring/HeuristicLab.Problems.Orienteering/3.3/Shakers/OrienteeringShakingOperator.cs	(revision 17524)
+++ /branches/2521_ProblemRefactoring/HeuristicLab.Problems.Orienteering/3.3/Shakers/OrienteeringShakingOperator.cs	(revision 17525)
@@ -22,4 +22,5 @@
 using System.Collections.Generic;
 using System.Linq;
+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.Orienteering {
@@ -64,21 +64,6 @@
       get { return (ILookupParameter<IntegerVector>)Parameters["IntegerVector"]; }
     }
-    public ILookupParameter<DoubleValue> MaximumDistanceParameter {
-      get { return (ILookupParameter<DoubleValue>)Parameters["MaximumDistance"]; }
-    }
-    public ILookupParameter<IntValue> StartingPointParameter {
-      get { return (ILookupParameter<IntValue>)Parameters["StartingPoint"]; }
-    }
-    public ILookupParameter<IntValue> TerminalPointParameter {
-      get { return (ILookupParameter<IntValue>)Parameters["TerminalPoint"]; }
-    }
-    public ILookupParameter<DistanceMatrix> DistanceMatrixParameter {
-      get { return (ILookupParameter<DistanceMatrix>)Parameters["DistanceMatrix"]; }
-    }
-    public ILookupParameter<DoubleArray> ScoresParameter {
-      get { return (ILookupParameter<DoubleArray>)Parameters["Scores"]; }
-    }
-    public ILookupParameter<DoubleValue> PointVisitingCostsParameter {
-      get { return (ILookupParameter<DoubleValue>)Parameters["PointVisitingCosts"]; }
+    public ILookupParameter<IOrienteeringProblemData> OrienteeringProblemDataParameter {
+      get { return (ILookupParameter<IOrienteeringProblemData>)Parameters["OrienteeringProblemData"]; }
     }
 
@@ -99,10 +84,5 @@
 
       Parameters.Add(new LookupParameter<IntegerVector>("IntegerVector", "The Orienteering Solution given in path representation."));
-      Parameters.Add(new LookupParameter<DoubleValue>("MaximumDistance", "The maximum distance constraint for a Orienteering solution."));
-      Parameters.Add(new LookupParameter<IntValue>("StartingPoint", "Index of the starting point."));
-      Parameters.Add(new LookupParameter<IntValue>("TerminalPoint", "Index of the ending point."));
-      Parameters.Add(new LookupParameter<DistanceMatrix>("DistanceMatrix", "The matrix which contains the distances between the points."));
-      Parameters.Add(new LookupParameter<DoubleArray>("Scores", "The scores of the points."));
-      Parameters.Add(new LookupParameter<DoubleValue>("PointVisitingCosts", "The costs for visiting a point."));
+      Parameters.Add(new LookupParameter<IOrienteeringProblemData>("OrienteeringProblemData", "The main data that comprises the orienteering problem."));
 
       Parameters.Add(new LookupParameter<IRandom>("Random", "The random number generator that will be used."));
@@ -115,11 +95,6 @@
     public override IOperation Apply() {
       var initialTour = IntegerVectorParameter.ActualValue;
-      var distances = DistanceMatrixParameter.ActualValue;
-      var scores = ScoresParameter.ActualValue;
-      var startingPoint = StartingPointParameter.ActualValue.Value;
-      var terminalPoint = TerminalPointParameter.ActualValue.Value;
-      var pointVisitingCosts = PointVisitingCostsParameter.ActualValue.Value;
-      double maxDistance = MaximumDistanceParameter.ActualValue.Value;
-      int numPoints = scores.Length;
+      var data = OrienteeringProblemDataParameter.ActualValue;
+      int numPoints = data.RoutingData.Cities;
 
       if (NeighborhoodCountParameter.ActualValue == null)
@@ -142,11 +117,11 @@
           from point in Enumerable.Range(0, numPoints)
           // Calculate the distance when going from the starting point to this point and then to the end point
-          let distance = distances[startingPoint, point] + distances[point, terminalPoint] + pointVisitingCosts
+          let distance = data.RoutingData.GetDistance(data.StartingPoint, point) + data.RoutingData.GetDistance(point, data.TerminalPoint) + data.PointVisitingCosts
           // If this distance is feasible and the point is neither starting nor ending point, check the point
-          where distance < maxDistance && point != startingPoint && point != terminalPoint
+          where distance < data.MaximumTravelCosts && point != data.StartingPoint && point != data.TerminalPoint
           // The point was not yet visited, so add it to the candidate list
           where !initialTour.Contains(point)
           // Calculate the utility of the point at this position
-          let utility = scores[point]
+          let utility = data.GetScore(point)
           orderby utility
           select point
@@ -154,5 +129,5 @@
 
         // Initialize the new tour
-        var actualTour = new List<int> { startingPoint };
+        var actualTour = new List<int> { data.StartingPoint };
 
         // Perform the insertions according to the utility sorting
@@ -160,5 +135,5 @@
 
         // Bring the tour back to be feasible 
-        CleanupTour(actualTour, distances, maxDistance, pointVisitingCosts);
+        CleanupTour(actualTour, data);
 
         // Set new Tour
@@ -213,20 +188,20 @@
     }
 
-    private void CleanupTour(List<int> actualTour, DistanceMatrix distances, double maxDistance, double pointVisitingCosts) {
+    private void CleanupTour(List<int> actualTour, IOrienteeringProblemData data) {
       // Sort the points on the tour according to their costs savings when removed
       var distanceSavings = (
         from removePosition in Enumerable.Range(1, actualTour.Count - 2)
-        let saving = distances.CalculateRemovementSaving(actualTour, removePosition, pointVisitingCosts)
+        let saving = OrienteeringProblem.CalculateRemovementSaving(data, actualTour, removePosition)
         orderby saving descending
         select new SavingInfo { Index = removePosition, Saving = saving }
       ).ToList();
 
-      double tourLength = distances.CalculateTourLength(actualTour, pointVisitingCosts);
+      double tourLength = OrienteeringProblem.CalculateTravelCosts(data, actualTour);
 
       // As long as the created path is infeasible, remove elements
-      while (tourLength > maxDistance) {
+      while (tourLength > data.MaximumTravelCosts) {
         // Remove the point that frees the largest distance
         // Note, distance savings are not updated after removal
-        tourLength -= distances.CalculateRemovementSaving(actualTour, distanceSavings[0].Index, pointVisitingCosts);
+        tourLength -= OrienteeringProblem.CalculateRemovementSaving(data, actualTour, distanceSavings[0].Index);
         actualTour.RemoveAt(distanceSavings[0].Index);
 
Index: /branches/2521_ProblemRefactoring/HeuristicLab.Problems.PTSP/3.3/ProbabilisticTSPData.cs
===================================================================
--- /branches/2521_ProblemRefactoring/HeuristicLab.Problems.PTSP/3.3/ProbabilisticTSPData.cs	(revision 17524)
+++ /branches/2521_ProblemRefactoring/HeuristicLab.Problems.PTSP/3.3/ProbabilisticTSPData.cs	(revision 17525)
@@ -58,9 +58,5 @@
     }
     public ProbabilisticTSPData(ITSPData tspData, double[] probabilities)
-      : base(tspData.Name, tspData.Description) {
-      if (tspData.Cities != probabilities.Length) throw new ArgumentException("Unequal number of cities and probabilities.");
-      TSPData = tspData;
-      Probabilities = new PercentArray(probabilities, @readonly: true);
-    }
+      : this(tspData, new PercentArray(probabilities, @readonly: true)) { }
     public ProbabilisticTSPData(ITSPData tspData, PercentArray probabilities)
       : base(tspData.Name, tspData.Description) {
Index: /branches/2521_ProblemRefactoring/HeuristicLab.Problems.TravelingSalesman/3.3/TSP.cs
===================================================================
--- /branches/2521_ProblemRefactoring/HeuristicLab.Problems.TravelingSalesman/3.3/TSP.cs	(revision 17524)
+++ /branches/2521_ProblemRefactoring/HeuristicLab.Problems.TravelingSalesman/3.3/TSP.cs	(revision 17525)
@@ -47,5 +47,6 @@
     [Storable] public IValueParameter<ITSPData> TSPDataParameter { get; private set; }
     [Storable] public IValueParameter<ITSPSolution> BestKnownSolutionParameter { get; private set; }
-    [Storable] public IResultParameter<ITSPSolution> BestTSPSolutionParameter { get; private set; }
+    [Storable] protected IResultParameter<ITSPSolution> BestTSPSolutionParameter { get; private set; }
+    public IResultDefinition<ITSPSolution> BestTSPSolution => BestTSPSolutionParameter;
 
     public ITSPData TSPData {
Index: /branches/2521_ProblemRefactoring/HeuristicLab.Problems.TravelingSalesman/3.3/TSPData.cs
===================================================================
--- /branches/2521_ProblemRefactoring/HeuristicLab.Problems.TravelingSalesman/3.3/TSPData.cs	(revision 17524)
+++ /branches/2521_ProblemRefactoring/HeuristicLab.Problems.TravelingSalesman/3.3/TSPData.cs	(revision 17525)
@@ -21,4 +21,5 @@
 
 using System;
+using System.Collections.Generic;
 using HEAL.Attic;
 using HeuristicLab.Common;
@@ -34,4 +35,5 @@
 
     double GetDistance(int fromCity, int toCity);
+    double GetPathDistance(IEnumerable<int> path, bool closed = true);
     ITSPSolution GetSolution(Permutation tspTour, double tourLength);
     TSPData Export();
@@ -85,5 +87,18 @@
 
     public double GetDistance(int fromCity, int toCity) => Matrix[fromCity, toCity];
-
+    public double GetPathDistance(IEnumerable<int> path, bool closed = true) {
+      var iter = path.GetEnumerator();
+      if (!iter.MoveNext()) return 0;
+      var start = iter.Current;
+      var prev = start;
+      var distance = 0.0;
+      while (iter.MoveNext()) {
+        var cur = iter.Current;
+        distance += Matrix[prev, cur];
+        prev = cur;
+      }
+      if (closed) distance += Matrix[prev, start];
+      return distance;
+    }
     public TSPData Export() {
       return new TSPData() {
@@ -133,4 +148,18 @@
 
     public abstract double GetDistance(double fromX, double fromY, double toX, double toY);
+    public double GetPathDistance(IEnumerable<int> path, bool closed = true) {
+      var iter = path.GetEnumerator();
+      if (!iter.MoveNext()) return 0;
+      var start = iter.Current;
+      var prev = start;
+      var distance = 0.0;
+      while (iter.MoveNext()) {
+        var cur = iter.Current;
+        distance += GetDistance(prev, cur);
+        prev = cur;
+      }
+      if (closed) distance += GetDistance(prev, start);
+      return distance;
+    }
 
     public virtual ITSPSolution GetSolution(Permutation tour, double tourLength) {
