Index: trunk/sources/HeuristicLab.Algorithms.SGA/3.3/HeuristicLab.Algorithms.SGA-3.3.csproj
===================================================================
--- trunk/sources/HeuristicLab.Algorithms.SGA/3.3/HeuristicLab.Algorithms.SGA-3.3.csproj	(revision 2974)
+++ trunk/sources/HeuristicLab.Algorithms.SGA/3.3/HeuristicLab.Algorithms.SGA-3.3.csproj	(revision 2975)
@@ -83,5 +83,7 @@
   <ItemGroup>
     <Compile Include="HeuristicLabAlgorithmsSGAPlugin.cs" />
-    <Compile Include="SGA.cs" />
+    <Compile Include="SGA.cs">
+      <SubType>Code</SubType>
+    </Compile>
     <Compile Include="SGAOperator.cs" />
     <Compile Include="Properties\AssemblyInfo.cs" />
Index: trunk/sources/HeuristicLab.Algorithms.SGA/3.3/SGA.cs
===================================================================
--- trunk/sources/HeuristicLab.Algorithms.SGA/3.3/SGA.cs	(revision 2974)
+++ trunk/sources/HeuristicLab.Algorithms.SGA/3.3/SGA.cs	(revision 2975)
@@ -38,168 +38,242 @@
   [Creatable("Algorithms")]
   public sealed class SGA : EngineAlgorithm {
-    [Storable]
-    private PopulationCreator populationCreator;
-    [Storable]
-    private SGAOperator sgaOperator;
-
-    private ValueParameter<IntData> PopulationSizeParameter {
-      get { return (ValueParameter<IntData>)Parameters["PopulationSize"]; }
-    }
-    private ConstrainedValueParameter<ISelector> SelectorParameter {
-      get { return (ConstrainedValueParameter<ISelector>)Parameters["Selector"]; }
-    }
-    private ConstrainedValueParameter<ICrossover> CrossoverParameter {
-      get { return (ConstrainedValueParameter<ICrossover>)Parameters["Crossover"]; }
-    }
-    private OptionalConstrainedValueParameter<IManipulator> MutatorParameter {
-      get { return (OptionalConstrainedValueParameter<IManipulator>)Parameters["Mutator"]; }
-    }
-    private ValueParameter<IntData> ElitesParameter {
-      get { return (ValueParameter<IntData>)Parameters["Elites"]; }
-    }
-
-    public override Type ProblemType {
-      get { return typeof(ISingleObjectiveProblem); }
-    }
-    public new ISingleObjectiveProblem Problem {
-      get { return (ISingleObjectiveProblem)base.Problem; }
-      set { base.Problem = value; }
-    }
-
-    public SGA()
-      : base() {
-      Parameters.Add(new ValueParameter<IntData>("Seed", "The random seed used to initialize the new pseudo random number generator.", new IntData(0)));
-      Parameters.Add(new ValueParameter<BoolData>("SetSeedRandomly", "True if the random seed should be set to a random value, otherwise false.", new BoolData(true)));
-      Parameters.Add(new ValueParameter<IntData>("PopulationSize", "The size of the population of solutions.", new IntData(100)));
-      Parameters.Add(new ConstrainedValueParameter<ISelector>("Selector", "The operator used to select solutions for reproduction."));
-      Parameters.Add(new ConstrainedValueParameter<ICrossover>("Crossover", "The operator used to cross solutions."));
-      Parameters.Add(new ValueParameter<DoubleData>("MutationProbability", "The probability that the mutation operator is applied on a solution.", new DoubleData(0.05)));
-      Parameters.Add(new OptionalConstrainedValueParameter<IManipulator>("Mutator", "The operator used to mutate solutions."));
-      Parameters.Add(new ValueParameter<IntData>("Elites", "The numer of elite solutions which are kept in each generation.", new IntData(1)));
-      Parameters.Add(new ValueParameter<IntData>("MaximumGenerations", "The maximum number of generations which should be processed.", new IntData(1000)));
-
-      PopulationSizeParameter.ValueChanged += new EventHandler(PopulationSizeParameter_ValueChanged);
-      ElitesParameter.ValueChanged += new EventHandler(ElitesParameter_ValueChanged);
-
-      RandomCreator randomCreator = new RandomCreator();
-      populationCreator = new PopulationCreator();
-      sgaOperator = new SGAOperator();
-
-      randomCreator.RandomParameter.ActualName = "Random";
-      randomCreator.SeedParameter.ActualName = "Seed";
-      randomCreator.SeedParameter.Value = null;
-      randomCreator.SetSeedRandomlyParameter.ActualName = "SetSeedRandomly";
-      randomCreator.SetSeedRandomlyParameter.Value = null;
-      randomCreator.Successor = populationCreator;
-
-      populationCreator.PopulationSizeParameter.ActualName = "PopulationSize";
-      populationCreator.PopulationSizeParameter.Value = null;
-      populationCreator.Successor = sgaOperator;
-
-      sgaOperator.SelectorParameter.ActualName = "Selector";
-      sgaOperator.CrossoverParameter.ActualName = "Crossover";
-      sgaOperator.ElitesParameter.ActualName = "Elites";
-      sgaOperator.MaximumGenerationsParameter.ActualName = "MaximumGenerations";
-      sgaOperator.MutatorParameter.ActualName = "Mutator";
-      sgaOperator.MutationProbabilityParameter.ActualName = "MutationProbability";
-      sgaOperator.RandomParameter.ActualName = "Random";
-      sgaOperator.ResultsParameter.ActualName = "Results";
-
-      OperatorGraph.InitialOperator = randomCreator;
-
-      if (ApplicationManager.Manager != null) {
-        var selectors = ApplicationManager.Manager.GetInstances<ISelector>().Where(x => !(x is IMultiObjectiveSelector)).OrderBy(x => x.Name);
-        foreach (ISelector selector in selectors) {
-          selector.CopySelected = new BoolData(true);
-          selector.NumberOfSelectedSubScopesParameter.Value = new IntData(2 * (PopulationSizeParameter.Value.Value - ElitesParameter.Value.Value));
-          if (selector is IStochasticOperator) ((IStochasticOperator)selector).RandomParameter.ActualName = "Random";
-          SelectorParameter.ValidValues.Add(selector);
-        }
-      }
-    }
-
-    public override IDeepCloneable Clone(Cloner cloner) {
-      SGA clone = (SGA)base.Clone(cloner);
-      clone.populationCreator = (PopulationCreator)cloner.Clone(populationCreator);
-      clone.sgaOperator = (SGAOperator)cloner.Clone(sgaOperator);
-      return clone;
-    }
-
-    private void ElitesParameter_ValueChanged(object sender, EventArgs e) {
-      foreach (ISelector selector in SelectorParameter.ValidValues)
-        selector.NumberOfSelectedSubScopesParameter.Value = new IntData(2 * (PopulationSizeParameter.Value.Value - ElitesParameter.Value.Value));
-    }
-    private void PopulationSizeParameter_ValueChanged(object sender, EventArgs e) {
-      foreach (ISelector selector in SelectorParameter.ValidValues)
-        selector.NumberOfSelectedSubScopesParameter.Value = new IntData(2 * (PopulationSizeParameter.Value.Value - ElitesParameter.Value.Value));
-    }
-
-    protected override void DeregisterProblemEvents() {
-      Problem.MaximizationChanged -= new EventHandler(Problem_MaximizationChanged);
-      base.DeregisterProblemEvents();
-    }
-    protected override void RegisterProblemEvents() {
-      base.RegisterProblemEvents();
-      Problem.MaximizationChanged += new EventHandler(Problem_MaximizationChanged);
-    }
-
-    protected override void OnProblemChanged() {
-      if (Problem.SolutionCreator is IStochasticOperator) ((IStochasticOperator)Problem.SolutionCreator).RandomParameter.ActualName = "Random";
-      if (Problem.Evaluator is IStochasticOperator) ((IStochasticOperator)Problem.Evaluator).RandomParameter.ActualName = "Random";
-      foreach (IStochasticOperator op in Problem.Operators.OfType<IStochasticOperator>())
-        op.RandomParameter.ActualName = "Random";
-
-      populationCreator.SolutionCreatorParameter.Value = Problem.SolutionCreator;
-      populationCreator.EvaluatorParameter.Value = Problem.Evaluator;
-      sgaOperator.MaximizationParameter.Value = Problem.Maximization;
-      sgaOperator.QualityParameter.ActualName = Problem.Evaluator.QualityParameter.ActualName;
-      sgaOperator.EvaluatorParameter.Value = Problem.Evaluator;
-
-      foreach (ISingleObjectiveSelector op in SelectorParameter.ValidValues.OfType<ISingleObjectiveSelector>()) {
-        op.MaximizationParameter.Value = Problem.Maximization;
-        op.QualityParameter.ActualName = Problem.Evaluator.QualityParameter.ActualName;
-      }
-
-      ICrossover oldCrossover = CrossoverParameter.Value;
-      CrossoverParameter.ValidValues.Clear();
-      foreach (ICrossover crossover in Problem.Operators.OfType<ICrossover>().OrderBy(x => x.Name))
-        CrossoverParameter.ValidValues.Add(crossover);
-      if (oldCrossover != null) {
-        CrossoverParameter.Value = CrossoverParameter.ValidValues.FirstOrDefault(x => x.GetType() == oldCrossover.GetType());
-      }
-
-      IManipulator oldMutator = MutatorParameter.Value;
-      MutatorParameter.ValidValues.Clear();
-      foreach (IManipulator mutator in Problem.Operators.OfType<IManipulator>().OrderBy(x => x.Name))
-        MutatorParameter.ValidValues.Add(mutator);
-      if (oldMutator != null) {
-        MutatorParameter.Value = MutatorParameter.ValidValues.FirstOrDefault(x => x.GetType() == oldMutator.GetType());
-      }
-
-      base.OnProblemChanged();
-    }
-    protected override void Problem_SolutionCreatorChanged(object sender, EventArgs e) {
-      if (Problem.SolutionCreator is IStochasticOperator) ((IStochasticOperator)Problem.SolutionCreator).RandomParameter.ActualName = "Random";
-      populationCreator.SolutionCreatorParameter.Value = Problem.SolutionCreator;
-      base.Problem_SolutionCreatorChanged(sender, e);
-    }
-    protected override void Problem_EvaluatorChanged(object sender, EventArgs e) {
-      if (Problem.Evaluator is IStochasticOperator) ((IStochasticOperator)Problem.Evaluator).RandomParameter.ActualName = "Random";
-
-      foreach (ISingleObjectiveSelector op in SelectorParameter.ValidValues.OfType<ISingleObjectiveSelector>()) {
-        op.QualityParameter.ActualName = Problem.Evaluator.QualityParameter.ActualName;
-      }
-
-      populationCreator.EvaluatorParameter.Value = Problem.Evaluator;
-      sgaOperator.QualityParameter.ActualName = Problem.Evaluator.QualityParameter.ActualName;
-      sgaOperator.EvaluatorParameter.Value = Problem.Evaluator;
-      base.Problem_EvaluatorChanged(sender, e);
-    }
-    private void Problem_MaximizationChanged(object sender, EventArgs e) {
-      sgaOperator.MaximizationParameter.Value = Problem.Maximization;
-      foreach (ISingleObjectiveSelector op in SelectorParameter.ValidValues.OfType<ISingleObjectiveSelector>()) {
-        op.MaximizationParameter.Value = Problem.Maximization;
-      }
-    }
+    //#region Private Members
+    //// store operator references in order to be able to access them easily after deserialization
+    //[Storable]
+    //private PopulationCreator populationCreator;
+    //[Storable]
+    //private SGAOperator sgaOperator;
+    //#endregion
+
+    //#region Problem Properties
+    //public override Type ProblemType {
+    //  get { return typeof(ISingleObjectiveProblem); }
+    //}
+    //public new ISingleObjectiveProblem Problem {
+    //  get { return (ISingleObjectiveProblem)base.Problem; }
+    //  set { base.Problem = value; }
+    //}
+    //#endregion
+
+    //#region Parameter Properties
+    //private ValueParameter<IntData> SeedParameter {
+    //  get { return (ValueParameter<IntData>)Parameters["Seed"]; }
+    //}
+    //private ValueParameter<BoolData> SetSeedRandomlyParameter {
+    //  get { return (ValueParameter<BoolData>)Parameters["SetSeedRandomly"]; }
+    //}
+    //private ValueParameter<IntData> PopulationSizeParameter {
+    //  get { return (ValueParameter<IntData>)Parameters["PopulationSize"]; }
+    //}
+    //private ConstrainedValueParameter<ISelector> SelectorParameter {
+    //  get { return (ConstrainedValueParameter<ISelector>)Parameters["Selector"]; }
+    //}
+    //private ConstrainedValueParameter<ICrossover> CrossoverParameter {
+    //  get { return (ConstrainedValueParameter<ICrossover>)Parameters["Crossover"]; }
+    //}
+    //private ValueParameter<DoubleData> MutationProbabilityParameter {
+    //  get { return (ValueParameter<DoubleData>)Parameters["MutationProbability"]; }
+    //}
+    //private OptionalConstrainedValueParameter<IManipulator> MutatorParameter {
+    //  get { return (OptionalConstrainedValueParameter<IManipulator>)Parameters["Mutator"]; }
+    //}
+    //private ValueParameter<IntData> ElitesParameter {
+    //  get { return (ValueParameter<IntData>)Parameters["Elites"]; }
+    //}
+    //private ValueParameter<IntData> MaximumGenerationsParameter {
+    //  get { return (ValueParameter<IntData>)Parameters["MaximumGenerations"]; }
+    //}
+    //#endregion
+
+    //#region Properties
+    //public IntData Seed {
+    //  get { return SeedParameter.Value; }
+    //  set { SeedParameter.Value = value; }
+    //}
+    //public BoolData SetSeedRandomly {
+    //  get { return SetSeedRandomlyParameter.Value; }
+    //  set { SetSeedRandomlyParameter.Value = value; }
+    //}
+    //public IntData PopulationSize {
+    //  get { return PopulationSizeParameter.Value; }
+    //  set { PopulationSizeParameter.Value = value; }
+    //}
+    //public ISelector Selector {
+    //  get { return SelectorParameter.Value; }
+    //  set { SelectorParameter.Value = value; }
+    //}
+    //public ICrossover Crossover {
+    //  get { return CrossoverParameter.Value; }
+    //  set { CrossoverParameter.Value = value; }
+    //}
+    //public DoubleData MutationProbability {
+    //  get { return MutationProbabilityParameter.Value; }
+    //  set { MutationProbabilityParameter.Value = value; }
+    //}
+    //public IManipulator Mutator {
+    //  get { return MutatorParameter.Value; }
+    //  set { MutatorParameter.Value = value; }
+    //}
+    //public IntData Elites {
+    //  get { return ElitesParameter.Value; }
+    //  set { ElitesParameter.Value = value; }
+    //}
+    //public IntData MaximumGenerations {
+    //  get { return MaximumGenerationsParameter.Value; }
+    //  set { MaximumGenerationsParameter.Value = value; }
+    //}
+    //#endregion
+
+    //#region Persistence Properties
+    //[Storable]
+    //private object RestoreEvents {
+    //  get { return null; }
+    //  set { RegisterEvents(); }
+    //}
+    //#endregion
+
+    //public SGA()
+    //  : base() {
+    //  Parameters.Add(new ValueParameter<IntData>("Seed", "The random seed used to initialize the new pseudo random number generator.", new IntData(0)));
+    //  Parameters.Add(new ValueParameter<BoolData>("SetSeedRandomly", "True if the random seed should be set to a random value, otherwise false.", new BoolData(true)));
+    //  Parameters.Add(new ValueParameter<IntData>("PopulationSize", "The size of the population of solutions.", new IntData(100)));
+    //  Parameters.Add(new ConstrainedValueParameter<ISelector>("Selector", "The operator used to select solutions for reproduction."));
+    //  Parameters.Add(new ConstrainedValueParameter<ICrossover>("Crossover", "The operator used to cross solutions."));
+    //  Parameters.Add(new ValueParameter<DoubleData>("MutationProbability", "The probability that the mutation operator is applied on a solution.", new DoubleData(0.05)));
+    //  Parameters.Add(new OptionalConstrainedValueParameter<IManipulator>("Mutator", "The operator used to mutate solutions."));
+    //  Parameters.Add(new ValueParameter<IntData>("Elites", "The numer of elite solutions which are kept in each generation.", new IntData(1)));
+    //  Parameters.Add(new ValueParameter<IntData>("MaximumGenerations", "The maximum number of generations which should be processed.", new IntData(1000)));
+
+    //  RandomCreator randomCreator = new RandomCreator();
+    //  populationCreator = new PopulationCreator();
+    //  sgaOperator = new SGAOperator();
+
+    //  randomCreator.RandomParameter.ActualName = "Random";
+    //  randomCreator.SeedParameter.ActualName = "Seed";
+    //  randomCreator.SeedParameter.Value = null;
+    //  randomCreator.SetSeedRandomlyParameter.ActualName = "SetSeedRandomly";
+    //  randomCreator.SetSeedRandomlyParameter.Value = null;
+    //  randomCreator.Successor = populationCreator;
+
+    //  populationCreator.PopulationSizeParameter.ActualName = "PopulationSize";
+    //  populationCreator.PopulationSizeParameter.Value = null;
+    //  populationCreator.Successor = sgaOperator;
+
+    //  sgaOperator.SelectorParameter.ActualName = "Selector";
+    //  sgaOperator.CrossoverParameter.ActualName = "Crossover";
+    //  sgaOperator.ElitesParameter.ActualName = "Elites";
+    //  sgaOperator.MaximumGenerationsParameter.ActualName = "MaximumGenerations";
+    //  sgaOperator.MutatorParameter.ActualName = "Mutator";
+    //  sgaOperator.MutationProbabilityParameter.ActualName = "MutationProbability";
+    //  sgaOperator.RandomParameter.ActualName = "Random";
+    //  sgaOperator.ResultsParameter.ActualName = "Results";
+
+    //  OperatorGraph.InitialOperator = randomCreator;
+
+    //  if (ApplicationManager.Manager != null) {
+    //    var selectors = ApplicationManager.Manager.GetInstances<ISelector>().Where(x => !(x is IMultiObjectiveSelector)).OrderBy(x => x.Name);
+    //    foreach (ISelector selector in selectors)
+    //      SelectorParameter.ValidValues.Add(selector);
+    //    ParameterizeSelectors();
+    //  }
+
+    //  RegisterEvents();
+    //}
+
+    //public override IDeepCloneable Clone(Cloner cloner) {
+    //  SGA clone = (SGA)base.Clone(cloner);
+    //  clone.populationCreator = (PopulationCreator)cloner.Clone(populationCreator);
+    //  clone.sgaOperator = (SGAOperator)cloner.Clone(sgaOperator);
+    //  clone.RegisterEvents();
+    //  return clone;
+    //}
+
+    //#region Events
+    //protected override void OnProblemChanged() {
+    //  if (Problem.SolutionCreator is IStochasticOperator) ((IStochasticOperator)Problem.SolutionCreator).RandomParameter.ActualName = "Random";
+    //  if (Problem.Evaluator is IStochasticOperator) ((IStochasticOperator)Problem.Evaluator).RandomParameter.ActualName = "Random";
+    //  foreach (IStochasticOperator op in Problem.Operators.OfType<IStochasticOperator>())
+    //    op.RandomParameter.ActualName = "Random";
+
+    //  populationCreator.SolutionCreatorParameter.Value = Problem.SolutionCreator;
+    //  populationCreator.EvaluatorParameter.Value = Problem.Evaluator;
+    //  sgaOperator.MaximizationParameter.ActualName = Problem.MaximizationParameter.Name;
+    //  sgaOperator.QualityParameter.ActualName = Problem.Evaluator.QualityParameter.ActualName;
+    //  sgaOperator.EvaluatorParameter.Value = Problem.Evaluator;
+
+    //  foreach (ISingleObjectiveSelector op in SelectorParameter.ValidValues.OfType<ISingleObjectiveSelector>()) {
+    //    op.MaximizationParameter.ActualName = Problem.MaximizationParameter.Name;
+    //    op.QualityParameter.ActualName = Problem.Evaluator.QualityParameter.ActualName;
+    //  }
+
+    //  ICrossover oldCrossover = CrossoverParameter.Value;
+    //  CrossoverParameter.ValidValues.Clear();
+    //  foreach (ICrossover crossover in Problem.Operators.OfType<ICrossover>().OrderBy(x => x.Name))
+    //    CrossoverParameter.ValidValues.Add(crossover);
+    //  if (oldCrossover != null) {
+    //    CrossoverParameter.Value = CrossoverParameter.ValidValues.FirstOrDefault(x => x.GetType() == oldCrossover.GetType());
+    //  }
+
+    //  IManipulator oldMutator = MutatorParameter.Value;
+    //  MutatorParameter.ValidValues.Clear();
+    //  foreach (IManipulator mutator in Problem.Operators.OfType<IManipulator>().OrderBy(x => x.Name))
+    //    MutatorParameter.ValidValues.Add(mutator);
+    //  if (oldMutator != null) {
+    //    MutatorParameter.Value = MutatorParameter.ValidValues.FirstOrDefault(x => x.GetType() == oldMutator.GetType());
+    //  }
+
+    //  base.OnProblemChanged();
+    //}
+    //protected override void Problem_SolutionCreatorChanged(object sender, EventArgs e) {
+    //  if (Problem.SolutionCreator is IStochasticOperator) ((IStochasticOperator)Problem.SolutionCreator).RandomParameter.ActualName = "Random";
+    //  populationCreator.SolutionCreatorParameter.Value = Problem.SolutionCreator;
+    //  base.Problem_SolutionCreatorChanged(sender, e);
+    //}
+    //protected override void Problem_EvaluatorChanged(object sender, EventArgs e) {
+    //  if (Problem.Evaluator is IStochasticOperator) ((IStochasticOperator)Problem.Evaluator).RandomParameter.ActualName = "Random";
+
+    //  foreach (ISingleObjectiveSelector op in SelectorParameter.ValidValues.OfType<ISingleObjectiveSelector>()) {
+    //    op.QualityParameter.ActualName = Problem.Evaluator.QualityParameter.ActualName;
+    //  }
+
+    //  populationCreator.EvaluatorParameter.Value = Problem.Evaluator;
+    //  sgaOperator.QualityParameter.ActualName = Problem.Evaluator.QualityParameter.ActualName;
+    //  sgaOperator.EvaluatorParameter.Value = Problem.Evaluator;
+    //  base.Problem_EvaluatorChanged(sender, e);
+    //}
+    //private void ElitesParameter_ValueChanged(object sender, EventArgs e) {
+    //  foreach (ISelector selector in SelectorParameter.ValidValues)
+    //    selector.NumberOfSelectedSubScopesParameter.Value = new IntData(2 * (PopulationSizeParameter.Value.Value - ElitesParameter.Value.Value));
+    //}
+    //private void PopulationSizeParameter_ValueChanged(object sender, EventArgs e) {
+    //  foreach (ISelector selector in SelectorParameter.ValidValues)
+    //    selector.NumberOfSelectedSubScopesParameter.Value = new IntData(2 * (PopulationSizeParameter.Value.Value - ElitesParameter.Value.Value));
+    //}
+    //#endregion
+
+    //#region Helpers
+    //private void RegisterEvents() {
+    //  PopulationSizeParameter.ValueChanged += new EventHandler(PopulationSizeParameter_ValueChanged);
+    //  ElitesParameter.ValueChanged += new EventHandler(ElitesParameter_ValueChanged);
+    //}
+    //private void ParameterizeSelectors() {
+    //  foreach (ISelector selector in SelectorParameter.ValidValues) {
+    //    selector.CopySelected = new BoolData(true);
+    //    selector.NumberOfSelectedSubScopesParameter.Value = new IntData(2 * (PopulationSizeParameter.Value.Value - ElitesParameter.Value.Value));
+    //    if (selector is IStochasticOperator) ((IStochasticOperator)selector).RandomParameter.ActualName = "Random";
+    //  }
+    //}
+    //private void ParameterizePopulationCreator() {
+    //  populationCreator.SolutionCreatorParameter.ActualName = Problem.SolutionCreatorParameter.Name;
+    //  populationCreator.EvaluatorParameter.ActualName = Problem.EvaluatorParameter.Name;
+    //}
+    //private void ParameterizeSGAOperator() {
+    //  sgaOperator.MaximizationParameter.ActualName = Problem.MaximizationParameter.Name;
+    //  sgaOperator.QualityParameter.ActualName = Problem.Evaluator.QualityParameter.ActualName;
+    //  sgaOperator.EvaluatorParameter.ActualName = Problem.EvaluatorParameter.Name;
+    //}
+    //private void ParameterizeSolutionCreator() {
+    //}
+    //#endregion
   }
 }
Index: trunk/sources/HeuristicLab.Optimization/3.3/Algorithm.cs
===================================================================
--- trunk/sources/HeuristicLab.Optimization/3.3/Algorithm.cs	(revision 2974)
+++ trunk/sources/HeuristicLab.Optimization/3.3/Algorithm.cs	(revision 2975)
@@ -147,15 +147,19 @@
         ExceptionOccurred(this, new EventArgs<Exception>(exception));
     }
+
     protected virtual void DeregisterProblemEvents() {
       problem.SolutionCreatorChanged -= new EventHandler(Problem_SolutionCreatorChanged);
       problem.EvaluatorChanged -= new EventHandler(Problem_EvaluatorChanged);
+      problem.OperatorsChanged -= new EventHandler(Problem_OperatorsChanged);
     }
     protected virtual void RegisterProblemEvents() {
       problem.SolutionCreatorChanged += new EventHandler(Problem_SolutionCreatorChanged);
       problem.EvaluatorChanged += new EventHandler(Problem_EvaluatorChanged);
+      problem.OperatorsChanged += new EventHandler(Problem_OperatorsChanged);
     }
 
     protected virtual void Problem_SolutionCreatorChanged(object sender, EventArgs e) { }
     protected virtual void Problem_EvaluatorChanged(object sender, EventArgs e) { }
+    protected virtual void Problem_OperatorsChanged(object sender, EventArgs e) { }
     #endregion
   }
Index: trunk/sources/HeuristicLab.Optimization/3.3/Interfaces/IProblem.cs
===================================================================
--- trunk/sources/HeuristicLab.Optimization/3.3/Interfaces/IProblem.cs	(revision 2974)
+++ trunk/sources/HeuristicLab.Optimization/3.3/Interfaces/IProblem.cs	(revision 2975)
@@ -21,4 +21,5 @@
 
 using System;
+using System.Collections.Generic;
 using HeuristicLab.Core;
 
@@ -28,10 +29,13 @@
   /// </summary>
   public interface IProblem : IParameterizedNamedItem {
+    IParameter SolutionCreatorParameter { get; }
     ISolutionCreator SolutionCreator { get; }
+    IParameter EvaluatorParameter { get; }
     IEvaluator Evaluator { get; }
-    OperatorSet Operators { get; }
+    IEnumerable<IOperator> Operators { get; }
 
     event EventHandler SolutionCreatorChanged;
     event EventHandler EvaluatorChanged;
+    event EventHandler OperatorsChanged;
   }
 }
Index: trunk/sources/HeuristicLab.Optimization/3.3/Interfaces/ISingleObjectiveProblem.cs
===================================================================
--- trunk/sources/HeuristicLab.Optimization/3.3/Interfaces/ISingleObjectiveProblem.cs	(revision 2974)
+++ trunk/sources/HeuristicLab.Optimization/3.3/Interfaces/ISingleObjectiveProblem.cs	(revision 2975)
@@ -20,6 +20,5 @@
 #endregion
 
-using System;
-using HeuristicLab.Data;
+using HeuristicLab.Core;
 
 namespace HeuristicLab.Optimization {
@@ -28,8 +27,6 @@
   /// </summary>
   public interface ISingleObjectiveProblem : IProblem {
-    BoolData Maximization { get; }
+    IParameter MaximizationParameter { get; }
     new ISingleObjectiveEvaluator Evaluator { get; }
-
-    event EventHandler MaximizationChanged;
   }
 }
Index: trunk/sources/HeuristicLab.Problems.TSP/3.3/HeuristicLab.Problems.TSP-3.3.csproj
===================================================================
--- trunk/sources/HeuristicLab.Problems.TSP/3.3/HeuristicLab.Problems.TSP-3.3.csproj	(revision 2974)
+++ trunk/sources/HeuristicLab.Problems.TSP/3.3/HeuristicLab.Problems.TSP-3.3.csproj	(revision 2975)
@@ -84,4 +84,8 @@
   </ItemGroup>
   <ItemGroup>
+    <Compile Include="TSPCoordinatesPathEvaluator.cs" />
+    <Compile Include="ITSPDistanceMatrixPathEvaluator.cs" />
+    <Compile Include="ITSPCoordinatesPathEvaluator.cs" />
+    <Compile Include="ITSPPathEvaluator.cs" />
     <Compile Include="HeuristicLabProblemsTSPPlugin.cs" />
     <Compile Include="TSPEvaluator.cs" />
@@ -102,4 +106,8 @@
       <Project>{0E27A536-1C4A-4624-A65E-DC4F4F23E3E1}</Project>
       <Name>HeuristicLab.Common.Resources-3.2</Name>
+    </ProjectReference>
+    <ProjectReference Include="..\..\HeuristicLab.Common\3.2\HeuristicLab.Common-3.2.csproj">
+      <Project>{1FC004FC-59AF-4249-B1B6-FF25873A20E4}</Project>
+      <Name>HeuristicLab.Common-3.2</Name>
     </ProjectReference>
     <ProjectReference Include="..\..\HeuristicLab.Core\3.3\HeuristicLab.Core-3.3.csproj">
Index: trunk/sources/HeuristicLab.Problems.TSP/3.3/HeuristicLabProblemsTSPPlugin.cs.frame
===================================================================
--- trunk/sources/HeuristicLab.Problems.TSP/3.3/HeuristicLabProblemsTSPPlugin.cs.frame	(revision 2974)
+++ trunk/sources/HeuristicLab.Problems.TSP/3.3/HeuristicLabProblemsTSPPlugin.cs.frame	(revision 2975)
@@ -29,4 +29,5 @@
   [PluginFile("HeuristicLab.Problems.TSP-3.3.dll", PluginFileType.Assembly)]
   [PluginDependency("HeuristicLab.Collections", "3.3")]
+  [PluginDependency("HeuristicLab.Common", "3.2")]
   [PluginDependency("HeuristicLab.Common.Resources", "3.2")]
   [PluginDependency("HeuristicLab.Core", "3.3")]
Index: trunk/sources/HeuristicLab.Problems.TSP/3.3/ITSPCoordinatesPathEvaluator.cs
===================================================================
--- trunk/sources/HeuristicLab.Problems.TSP/3.3/ITSPCoordinatesPathEvaluator.cs	(revision 2975)
+++ trunk/sources/HeuristicLab.Problems.TSP/3.3/ITSPCoordinatesPathEvaluator.cs	(revision 2975)
@@ -0,0 +1,32 @@
+#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2010 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;
+
+namespace HeuristicLab.Problems.TSP {
+  /// <summary>
+  /// An interface which represents an evaluation operator which evaluates TSP solutions given in path representation using city coordinates.
+  /// </summary>
+  public interface ITSPCoordinatesPathEvaluator : ITSPPathEvaluator {
+    ILookupParameter<DoubleMatrixData> CoordinatesParameter { get; }
+  }
+}
Index: trunk/sources/HeuristicLab.Problems.TSP/3.3/ITSPDistanceMatrixPathEvaluator.cs
===================================================================
--- trunk/sources/HeuristicLab.Problems.TSP/3.3/ITSPDistanceMatrixPathEvaluator.cs	(revision 2975)
+++ trunk/sources/HeuristicLab.Problems.TSP/3.3/ITSPDistanceMatrixPathEvaluator.cs	(revision 2975)
@@ -0,0 +1,32 @@
+#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2010 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;
+
+namespace HeuristicLab.Problems.TSP {
+  /// <summary>
+  /// An interface which represents an evaluation operator which evaluates TSP solutions given in path representation using a distance matrix.
+  /// </summary>
+  public interface ITSPDistanceMatrixPathEvaluator : ITSPPathEvaluator {
+    ILookupParameter<DoubleMatrixData> DistanceMatrixParameter { get; }
+  }
+}
Index: trunk/sources/HeuristicLab.Problems.TSP/3.3/ITSPPathEvaluator.cs
===================================================================
--- trunk/sources/HeuristicLab.Problems.TSP/3.3/ITSPPathEvaluator.cs	(revision 2975)
+++ trunk/sources/HeuristicLab.Problems.TSP/3.3/ITSPPathEvaluator.cs	(revision 2975)
@@ -0,0 +1,32 @@
+#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2010 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.Encodings.Permutation;
+
+namespace HeuristicLab.Problems.TSP {
+  /// <summary>
+  /// An interface which represents an evaluation operator which evaluates TSP solutions given in path representation.
+  /// </summary>
+  public interface ITSPPathEvaluator : ITSPEvaluator {
+    ILookupParameter<Permutation> PermutationParameter { get; }
+  }
+}
Index: trunk/sources/HeuristicLab.Problems.TSP/3.3/TSP.cs
===================================================================
--- trunk/sources/HeuristicLab.Problems.TSP/3.3/TSP.cs	(revision 2974)
+++ trunk/sources/HeuristicLab.Problems.TSP/3.3/TSP.cs	(revision 2975)
@@ -21,6 +21,8 @@
 
 using System;
+using System.Collections.Generic;
 using System.Drawing;
 using System.Linq;
+using HeuristicLab.Common;
 using HeuristicLab.Core;
 using HeuristicLab.Data;
@@ -34,5 +36,4 @@
   [Item("TSP", "Represents a symmetric Traveling Salesman Problem.")]
   [Creatable("Problems")]
-  [EmptyStorableClass]
   public sealed class TSP : ParameterizedNamedItem, ISingleObjectiveProblem {
     public override Image ItemImage {
@@ -40,27 +41,48 @@
     }
 
-    private IValueParameter<BoolData> MaximizationParameter {
-      get { return (IValueParameter<BoolData>)Parameters["Maximization"]; }
-    }
-    public IValueParameter<DoubleMatrixData> CoordinatesParameter {
-      get { return (IValueParameter<DoubleMatrixData>)Parameters["Coordinates"]; }
-    }
-    public IValueParameter<DoubleData> BestKnownQualityParameter {
-      get { return (IValueParameter<DoubleData>)Parameters["BestKnownQuality"]; }
-    }
-    public IValueParameter<IPermutationCreator> SolutionCreatorParameter {
-      get { return (IValueParameter<IPermutationCreator>)Parameters["SolutionCreator"]; }
-    }
-    public IValueParameter<ITSPEvaluator> EvaluatorParameter {
-      get { return (IValueParameter<ITSPEvaluator>)Parameters["Evaluator"]; }
-    }
-
-    public BoolData Maximization {
-      get { return MaximizationParameter.Value; }
-    }
-    public ISolutionCreator SolutionCreator {
+    #region Parameter Properties
+    public ValueParameter<BoolData> MaximizationParameter {
+      get { return (ValueParameter<BoolData>)Parameters["Maximization"]; }
+    }
+    IParameter ISingleObjectiveProblem.MaximizationParameter {
+      get { return MaximizationParameter; }
+    }
+    public ValueParameter<DoubleMatrixData> CoordinatesParameter {
+      get { return (ValueParameter<DoubleMatrixData>)Parameters["Coordinates"]; }
+    }
+    public ValueParameter<IPermutationCreator> SolutionCreatorParameter {
+      get { return (ValueParameter<IPermutationCreator>)Parameters["SolutionCreator"]; }
+    }
+    IParameter IProblem.SolutionCreatorParameter {
+      get { return SolutionCreatorParameter; }
+    }
+    public ValueParameter<ITSPEvaluator> EvaluatorParameter {
+      get { return (ValueParameter<ITSPEvaluator>)Parameters["Evaluator"]; }
+    }
+    IParameter IProblem.EvaluatorParameter {
+      get { return EvaluatorParameter; }
+    }
+    public OptionalValueParameter<DoubleData> BestKnownQualityParameter {
+      get { return (OptionalValueParameter<DoubleData>)Parameters["BestKnownQuality"]; }
+    }
+    #endregion
+
+    #region Properties
+    public DoubleMatrixData Coordinates {
+      get { return CoordinatesParameter.Value; }
+      set { CoordinatesParameter.Value = value; }
+    }
+    public IPermutationCreator SolutionCreator {
       get { return SolutionCreatorParameter.Value; }
-    }
-    public ISingleObjectiveEvaluator Evaluator {
+      set { SolutionCreatorParameter.Value = value; }
+    }
+    ISolutionCreator IProblem.SolutionCreator {
+      get { return SolutionCreatorParameter.Value; }
+    }
+    public ITSPEvaluator Evaluator {
+      get { return EvaluatorParameter.Value; }
+      set { EvaluatorParameter.Value = value; }
+    }
+    ISingleObjectiveEvaluator ISingleObjectiveProblem.Evaluator {
       get { return EvaluatorParameter.Value; }
     }
@@ -68,8 +90,24 @@
       get { return EvaluatorParameter.Value; }
     }
+    public DoubleData BestKnownQuality {
+      get { return BestKnownQualityParameter.Value; }
+      set { BestKnownQualityParameter.Value = value; }
+    }
     private OperatorSet operators;
-    public OperatorSet Operators {
-      get { return operators; }
-    }
+    public IEnumerable<IOperator> Operators {
+      get {
+        if (operators == null) InitializeOperators();
+        return operators;
+      }
+    }
+    #endregion
+
+    #region Persistence Properties
+    [Storable]
+    private object RestoreEvents {
+      get { return null; }
+      set { RegisterEvents(); }
+    }
+    #endregion
 
     public TSP()
@@ -85,26 +123,15 @@
 
       creator.PermutationParameter.ActualName = "TSPTour";
-      creator.LengthParameter.Value = new IntData(0);
-      evaluator.CoordinatesParameter.ActualName = CoordinatesParameter.Name;
-      evaluator.PermutationParameter.ActualName = creator.PermutationParameter.ActualName;
       evaluator.QualityParameter.ActualName = "TSPTourLength";
-
-      MaximizationParameter.ValueChanged += new EventHandler(MaximizationParameter_ValueChanged);
-      SolutionCreatorParameter.ValueChanged += new EventHandler(SolutionCreatorParameter_ValueChanged);
-      EvaluatorParameter.ValueChanged += new EventHandler(EvaluatorParameter_ValueChanged);
-
-      operators = new OperatorSet();
-      if (ApplicationManager.Manager != null) {
-        var ops = ApplicationManager.Manager.GetInstances<IPermutationOperator>();
-        foreach (IPermutationCrossover op in ops.OfType<IPermutationCrossover>()) {
-          op.ParentsParameter.ActualName = creator.PermutationParameter.ActualName;
-          op.ChildParameter.ActualName = creator.PermutationParameter.ActualName;
-        }
-        foreach (IPermutationManipulator op in ops.OfType<IPermutationManipulator>()) {
-          op.PermutationParameter.ActualName = creator.PermutationParameter.ActualName;
-        }
-        foreach (IPermutationOperator op in ops)
-          operators.Add(op);
-      }
+      ParameterizeSolutionCreator();
+      ParameterizeEvaluator();
+
+      RegisterEvents();
+    }
+
+    public override IDeepCloneable Clone(Cloner cloner) {
+      TSP clone = (TSP)base.Clone(cloner);
+      clone.RegisterEvents();
+      return clone;
     }
 
@@ -112,24 +139,8 @@
       TSPLIBParser parser = new TSPLIBParser(filename);
       parser.Parse();
-      CoordinatesParameter.Value = new DoubleMatrixData(parser.Vertices);
-      int cities = CoordinatesParameter.Value.Rows;
-      SolutionCreatorParameter.Value.LengthParameter.Value = new IntData(cities);
-    }
-
-    private void MaximizationParameter_ValueChanged(object sender, EventArgs e) {
-      OnMaximizationChanged();
-    }
-    private void SolutionCreatorParameter_ValueChanged(object sender, EventArgs e) {
-      OnSolutionCreatorChanged();
-    }
-    private void EvaluatorParameter_ValueChanged(object sender, EventArgs e) {
-      OnEvaluatorChanged();
-    }
-
-    public event EventHandler MaximizationChanged;
-    private void OnMaximizationChanged() {
-      if (MaximizationChanged != null)
-        MaximizationChanged(this, EventArgs.Empty);
-    }
+      Coordinates = new DoubleMatrixData(parser.Vertices);
+    }
+
+    #region Events
     public event EventHandler SolutionCreatorChanged;
     private void OnSolutionCreatorChanged() {
@@ -142,4 +153,73 @@
         EvaluatorChanged(this, EventArgs.Empty);
     }
+    public event EventHandler OperatorsChanged;
+    private void OnOperatorsChanged() {
+      if (OperatorsChanged != null)
+        OperatorsChanged(this, EventArgs.Empty);
+    }
+
+    private void CoordinatesParameter_ValueChanged(object sender, EventArgs e) {
+      Coordinates.ItemChanged += new EventHandler<EventArgs<int, int>>(Coordinates_ItemChanged);
+      Coordinates.Reset += new EventHandler(Coordinates_Reset);
+      ParameterizeSolutionCreator();
+    }
+    private void Coordinates_ItemChanged(object sender, EventArgs<int, int> e) {
+    }
+    private void Coordinates_Reset(object sender, EventArgs e) {
+      ParameterizeSolutionCreator();
+    }
+    private void SolutionCreatorParameter_ValueChanged(object sender, EventArgs e) {
+      SolutionCreator.PermutationParameter.ActualNameChanged += new EventHandler(SolutionCreator_PermutationParameter_ActualNameChanged);
+      ParameterizeSolutionCreator();
+      ParameterizeEvaluator();
+      ParameterizeOperators();
+      OnSolutionCreatorChanged();
+    }
+    private void SolutionCreator_PermutationParameter_ActualNameChanged(object sender, EventArgs e) {
+      ParameterizeEvaluator();
+      ParameterizeOperators();
+    }
+    private void EvaluatorParameter_ValueChanged(object sender, EventArgs e) {
+      ParameterizeEvaluator();
+      OnEvaluatorChanged();
+    }
+    #endregion
+
+    #region Helpers
+    private void RegisterEvents() {
+      CoordinatesParameter.ValueChanged += new EventHandler(CoordinatesParameter_ValueChanged);
+      Coordinates.ItemChanged += new EventHandler<EventArgs<int, int>>(Coordinates_ItemChanged);
+      Coordinates.Reset += new EventHandler(Coordinates_Reset);
+      SolutionCreatorParameter.ValueChanged += new EventHandler(SolutionCreatorParameter_ValueChanged);
+      SolutionCreator.PermutationParameter.ActualNameChanged += new EventHandler(SolutionCreator_PermutationParameter_ActualNameChanged);
+      EvaluatorParameter.ValueChanged += new EventHandler(EvaluatorParameter_ValueChanged);
+    }
+    private void ParameterizeSolutionCreator() {
+      SolutionCreator.LengthParameter.Value = new IntData(Coordinates.Rows);
+    }
+    private void ParameterizeEvaluator() {
+      if (Evaluator is ITSPPathEvaluator)
+        ((ITSPPathEvaluator)Evaluator).PermutationParameter.ActualName = SolutionCreator.PermutationParameter.ActualName;
+      if (Evaluator is ITSPCoordinatesPathEvaluator)
+        ((ITSPCoordinatesPathEvaluator)Evaluator).CoordinatesParameter.ActualName = CoordinatesParameter.Name;
+    }
+    private void InitializeOperators() {
+      operators = new OperatorSet();
+      if (ApplicationManager.Manager != null) {
+        foreach (IPermutationOperator op in ApplicationManager.Manager.GetInstances<IPermutationOperator>())
+          operators.Add(op);
+        ParameterizeOperators();
+      }
+    }
+    private void ParameterizeOperators() {
+      foreach (IPermutationCrossover op in Operators.OfType<IPermutationCrossover>()) {
+        op.ParentsParameter.ActualName = SolutionCreator.PermutationParameter.ActualName;
+        op.ChildParameter.ActualName = SolutionCreator.PermutationParameter.ActualName;
+      }
+      foreach (IPermutationManipulator op in Operators.OfType<IPermutationManipulator>()) {
+        op.PermutationParameter.ActualName = SolutionCreator.PermutationParameter.ActualName;
+      }
+    }
+    #endregion
   }
 }
Index: trunk/sources/HeuristicLab.Problems.TSP/3.3/TSPCoordinatesPathEvaluator.cs
===================================================================
--- trunk/sources/HeuristicLab.Problems.TSP/3.3/TSPCoordinatesPathEvaluator.cs	(revision 2975)
+++ trunk/sources/HeuristicLab.Problems.TSP/3.3/TSPCoordinatesPathEvaluator.cs	(revision 2975)
@@ -0,0 +1,59 @@
+#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2010 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.Parameters;
+using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
+
+namespace HeuristicLab.Problems.TSP {
+  /// <summary>
+  /// A base class for operators which evaluate TSP solutions given in path representation using city coordinates.
+  /// </summary>
+  [Item("TSPCoordinatesPathEvaluator", "A base class for operators which evaluate TSP solutions given in path representation using city coordinates.")]
+  [EmptyStorableClass]
+  public abstract class TSPCoordinatesPathEvaluator : TSPPathEvaluator, ITSPCoordinatesPathEvaluator {
+    public ILookupParameter<DoubleMatrixData> CoordinatesParameter {
+      get { return (ILookupParameter<DoubleMatrixData>)Parameters["Coordinates"]; }
+    }
+
+    protected TSPCoordinatesPathEvaluator()
+      : base() {
+      Parameters.Add(new LookupParameter<DoubleMatrixData>("Coordinates", "The x- and y-Coordinates of the cities."));
+    }
+
+    protected sealed override double CalculateDistance(int a, int b) {
+      DoubleMatrixData coordinates = CoordinatesParameter.ActualValue;
+      return CalculateDistance(coordinates[a, 0], coordinates[a, 1],
+                               coordinates[b, 0], coordinates[b, 1]);
+    }
+
+    /// <summary>
+    /// Calculates the distance between two points.
+    /// </summary>
+    /// <param name="x1">The x-coordinate of point 1.</param>
+    /// <param name="y1">The y-coordinate of point 1.</param>
+    /// <param name="x2">The x-coordinate of point 2.</param>
+    /// <param name="y2">The y-coordinate of point 2.</param>
+    /// <returns>The calculated distance.</returns>
+    protected abstract double CalculateDistance(double x1, double y1, double x2, double y2);
+  }
+}
Index: trunk/sources/HeuristicLab.Problems.TSP/3.3/TSPDistanceMatrixPathEvaluator.cs
===================================================================
--- trunk/sources/HeuristicLab.Problems.TSP/3.3/TSPDistanceMatrixPathEvaluator.cs	(revision 2974)
+++ trunk/sources/HeuristicLab.Problems.TSP/3.3/TSPDistanceMatrixPathEvaluator.cs	(revision 2975)
@@ -22,5 +22,4 @@
 using HeuristicLab.Core;
 using HeuristicLab.Data;
-using HeuristicLab.Encodings.Permutation;
 using HeuristicLab.Parameters;
 using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
@@ -33,10 +32,7 @@
   [Creatable("Test")]
   [EmptyStorableClass]
-  public sealed class TSPDistanceMatrixPathEvaluator : TSPEvaluator {
-    public LookupParameter<DoubleMatrixData> DistanceMatrixParameter {
-      get { return (LookupParameter<DoubleMatrixData>)Parameters["DistanceMatrix"]; }
-    }
-    public LookupParameter<Permutation> PermutationParameter {
-      get { return (LookupParameter<Permutation>)Parameters["Permutation"]; }
+  public sealed class TSPDistanceMatrixPathEvaluator : TSPPathEvaluator, ITSPDistanceMatrixPathEvaluator {
+    public ILookupParameter<DoubleMatrixData> DistanceMatrixParameter {
+      get { return (ILookupParameter<DoubleMatrixData>)Parameters["DistanceMatrix"]; }
     }
 
@@ -44,18 +40,9 @@
       : base() {
       Parameters.Add(new LookupParameter<DoubleMatrixData>("DistanceMatrix", "The distance matrix of the cities."));
-      Parameters.Add(new LookupParameter<Permutation>("Permutation", "The TSP solution given in path representation which should be evaluated."));
     }
 
-    public override IOperation Apply() {
+    protected override double CalculateDistance(int a, int b) {
       DoubleMatrixData distanceMatrix = DistanceMatrixParameter.ActualValue;
-      Permutation permutation = PermutationParameter.ActualValue;
-
-      double length = 0;
-      for (int i = 0; i < permutation.Length - 1; i++)
-        length += distanceMatrix[permutation[i], permutation[i + 1]];
-      length += distanceMatrix[permutation[permutation.Length - 1], permutation[0]];
-      QualityParameter.ActualValue = new DoubleData(length);
-
-      return base.Apply();
+      return distanceMatrix[a, b];
     }
   }
Index: trunk/sources/HeuristicLab.Problems.TSP/3.3/TSPPathEvaluator.cs
===================================================================
--- trunk/sources/HeuristicLab.Problems.TSP/3.3/TSPPathEvaluator.cs	(revision 2974)
+++ trunk/sources/HeuristicLab.Problems.TSP/3.3/TSPPathEvaluator.cs	(revision 2975)
@@ -32,32 +32,21 @@
   [Item("TSPPathEvaluator", "A base class for operators which evaluate TSP solutions given in path representation.")]
   [EmptyStorableClass]
-  public abstract class TSPPathEvaluator : TSPEvaluator {
-    public LookupParameter<DoubleMatrixData> CoordinatesParameter {
-      get { return (LookupParameter<DoubleMatrixData>)Parameters["Coordinates"]; }
-    }
-    public LookupParameter<Permutation> PermutationParameter {
-      get { return (LookupParameter<Permutation>)Parameters["Permutation"]; }
+  public abstract class TSPPathEvaluator : TSPEvaluator, ITSPPathEvaluator {
+    public ILookupParameter<Permutation> PermutationParameter {
+      get { return (ILookupParameter<Permutation>)Parameters["Permutation"]; }
     }
 
     protected TSPPathEvaluator()
       : base() {
-      Parameters.Add(new LookupParameter<DoubleMatrixData>("Coordinates", "The x- and y-Coordinates of the cities."));
       Parameters.Add(new LookupParameter<Permutation>("Permutation", "The TSP solution given in path representation which should be evaluated."));
     }
 
-    public override IOperation Apply() {
-      DoubleMatrixData coordinates = CoordinatesParameter.ActualValue;
+    public sealed override IOperation Apply() {
       Permutation permutation = PermutationParameter.ActualValue;
 
       double length = 0;
       for (int i = 0; i < permutation.Length - 1; i++)
-        length += CalculateDistance(coordinates[permutation[i], 0],
-                                    coordinates[permutation[i], 1],
-                                    coordinates[permutation[i + 1], 0],
-                                    coordinates[permutation[i + 1], 1]);
-      length += CalculateDistance(coordinates[permutation[permutation.Length - 1], 0],
-                                  coordinates[permutation[permutation.Length - 1], 1],
-                                  coordinates[permutation[0], 0],
-                                  coordinates[permutation[0], 1]);
+        length += CalculateDistance(permutation[i], permutation[i + 1]);
+      length += CalculateDistance(permutation[permutation.Length - 1], permutation[0]);
       QualityParameter.ActualValue = new DoubleData(length);
 
@@ -66,12 +55,10 @@
 
     /// <summary>
-    /// Calculates the distance between two points.
+    /// Calculates the distance between two cities.
     /// </summary>
-    /// <param name="x1">The x-coordinate of point 1.</param>
-    /// <param name="y1">The y-coordinate of point 1.</param>
-    /// <param name="x2">The x-coordinate of point 2.</param>
-    /// <param name="y2">The y-coordinate of point 2.</param>
+    /// <param name="a">The index of the first city.</param>
+    /// <param name="b">The index of the second city.</param>
     /// <returns>The calculated distance.</returns>
-    protected abstract double CalculateDistance(double x1, double y1, double x2, double y2);
+    protected abstract double CalculateDistance(int a, int b);
   }
 }
Index: trunk/sources/HeuristicLab.Problems.TSP/3.3/TSPRoundedEuclideanPathEvaluator.cs
===================================================================
--- trunk/sources/HeuristicLab.Problems.TSP/3.3/TSPRoundedEuclideanPathEvaluator.cs	(revision 2974)
+++ trunk/sources/HeuristicLab.Problems.TSP/3.3/TSPRoundedEuclideanPathEvaluator.cs	(revision 2975)
@@ -31,5 +31,5 @@
   [Creatable("Test")]
   [EmptyStorableClass]
-  public sealed class TSPRoundedEuclideanPathEvaluator : TSPPathEvaluator {
+  public sealed class TSPRoundedEuclideanPathEvaluator : TSPCoordinatesPathEvaluator {
     /// <summary>
     /// Calculates the distance between two points using the rounded Euclidean distance metric.
