Index: branches/2522_RefactorPluginInfrastructure/HeuristicLab.Algorithms.DataAnalysis/3.4/NearestNeighbour/NearestNeighbourRegression.cs
===================================================================
--- branches/2522_RefactorPluginInfrastructure/HeuristicLab.Algorithms.DataAnalysis/3.4/NearestNeighbour/NearestNeighbourRegression.cs	(revision 15651)
+++ branches/2522_RefactorPluginInfrastructure/HeuristicLab.Algorithms.DataAnalysis/3.4/NearestNeighbour/NearestNeighbourRegression.cs	(revision 15973)
@@ -1,5 +1,5 @@
 #region License Information
 /* HeuristicLab
- * Copyright (C) 2002-2015 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ * Copyright (C) 2002-2018 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
  *
  * This file is part of HeuristicLab.
@@ -21,4 +21,5 @@
 
 using System;
+using System.Threading;
 using HeuristicLab.Common;
 using HeuristicLab.Core;
@@ -39,8 +40,13 @@
     private const string KParameterName = "K";
     private const string NearestNeighbourRegressionModelResultName = "Nearest neighbour regression solution";
+    private const string WeightsParameterName = "Weights";
 
     #region parameter properties
     public IFixedValueParameter<IntValue> KParameter {
       get { return (IFixedValueParameter<IntValue>)Parameters[KParameterName]; }
+    }
+
+    public IValueParameter<DoubleArray> WeightsParameter {
+      get { return (IValueParameter<DoubleArray>)Parameters[WeightsParameterName]; }
     }
     #endregion
@@ -52,4 +58,9 @@
         else KParameter.Value.Value = value;
       }
+    }
+
+    public DoubleArray Weights {
+      get { return WeightsParameter.Value; }
+      set { WeightsParameter.Value = value; }
     }
     #endregion
@@ -63,8 +74,17 @@
       : base() {
       Parameters.Add(new FixedValueParameter<IntValue>(KParameterName, "The number of nearest neighbours to consider for regression.", new IntValue(3)));
+      Parameters.Add(new OptionalValueParameter<DoubleArray>(WeightsParameterName, "Optional: use weights to specify individual scaling values for all features. If not set the weights are calculated automatically (each feature is scaled to unit variance)"));
       Problem = new RegressionProblem();
     }
+
     [StorableHook(HookType.AfterDeserialization)]
-    private void AfterDeserialization() { }
+    private void AfterDeserialization() {
+      // BackwardsCompatibility3.3
+      #region Backwards compatible code, remove with 3.4
+      if (!Parameters.ContainsKey(WeightsParameterName)) {
+        Parameters.Add(new OptionalValueParameter<DoubleArray>(WeightsParameterName, "Optional: use weights to specify individual scaling values for all features. If not set the weights are calculated automatically (each feature is scaled to unit variance)"));
+      }
+      #endregion
+    }
 
     public override IDeepCloneable Clone(Cloner cloner) {
@@ -73,20 +93,23 @@
 
     #region nearest neighbour
-    protected override void Run() {
-      var solution = CreateNearestNeighbourRegressionSolution(Problem.ProblemData, K);
+    protected override void Run(CancellationToken cancellationToken) {
+      double[] weights = null;
+      if (Weights != null) weights = Weights.CloneAsArray();
+      var solution = CreateNearestNeighbourRegressionSolution(Problem.ProblemData, K, weights);
       Results.Add(new Result(NearestNeighbourRegressionModelResultName, "The nearest neighbour regression solution.", solution));
     }
 
-    public static IRegressionSolution CreateNearestNeighbourRegressionSolution(IRegressionProblemData problemData, int k) {
+    public static IRegressionSolution CreateNearestNeighbourRegressionSolution(IRegressionProblemData problemData, int k, double[] weights = null) {
       var clonedProblemData = (IRegressionProblemData)problemData.Clone();
-      return new NearestNeighbourRegressionSolution(clonedProblemData, Train(problemData, k));
+      return new NearestNeighbourRegressionSolution(Train(problemData, k, weights), clonedProblemData);
     }
 
-    public static INearestNeighbourModel Train(IRegressionProblemData problemData, int k) {
+    public static INearestNeighbourModel Train(IRegressionProblemData problemData, int k, double[] weights = null) {
       return new NearestNeighbourModel(problemData.Dataset,
         problemData.TrainingIndices,
         k,
         problemData.TargetVariable,
-        problemData.AllowedInputVariables);
+        problemData.AllowedInputVariables,
+        weights);
     }
     #endregion
