Index: /trunk/sources/HeuristicLab.Algorithms.DataAnalysis/3.4/GaussianProcess/CovarianceConst.cs
===================================================================
--- /trunk/sources/HeuristicLab.Algorithms.DataAnalysis/3.4/GaussianProcess/CovarianceConst.cs	(revision 8611)
+++ /trunk/sources/HeuristicLab.Algorithms.DataAnalysis/3.4/GaussianProcess/CovarianceConst.cs	(revision 8612)
@@ -31,22 +31,20 @@
   [Item(Name = "CovarianceConst",
     Description = "Constant covariance function for Gaussian processes.")]
-  public class CovarianceConst : CovarianceFunction {
+  public sealed class CovarianceConst : ParameterizedNamedItem, ICovarianceFunction {
 
+    [Storable]
+    private double scale;
+    [Storable]
+    private readonly HyperParameter<DoubleValue> scaleParameter;
     public IValueParameter<DoubleValue> ScaleParameter {
       get { return scaleParameter; }
     }
 
-    [Storable]
-    private readonly HyperParameter<DoubleValue> scaleParameter;
-
-    [Storable]
-    private double scale;
-
     [StorableConstructor]
-    protected CovarianceConst(bool deserializing)
+    private CovarianceConst(bool deserializing)
       : base(deserializing) {
     }
 
-    protected CovarianceConst(CovarianceConst original, Cloner cloner)
+    private CovarianceConst(CovarianceConst original, Cloner cloner)
       : base(original, cloner) {
       this.scaleParameter = cloner.Clone(original.scaleParameter);
@@ -58,4 +56,7 @@
     public CovarianceConst()
       : base() {
+      Name = ItemName;
+      Description = ItemDescription;
+
       scaleParameter = new HyperParameter<DoubleValue>("Scale", "The scale of the constant covariance function.");
       Parameters.Add(scaleParameter);
@@ -70,5 +71,5 @@
     // caching
     private void RegisterEvents() {
-      AttachValueChangeHandler<DoubleValue, double>(scaleParameter, () => { scale = scaleParameter.Value.Value; });
+      Util.AttachValueChangeHandler<DoubleValue, double>(scaleParameter, () => { scale = scaleParameter.Value.Value; });
     }
 
@@ -78,9 +79,9 @@
     }
 
-    public override int GetNumberOfParameters(int numberOfVariables) {
+    public int GetNumberOfParameters(int numberOfVariables) {
       return scaleParameter.Fixed ? 0 : 1;
     }
 
-    public override void SetParameter(double[] hyp) {
+    public void SetParameter(double[] hyp) {
       if (!scaleParameter.Fixed && hyp.Length == 1) {
         scaleParameter.SetValue(new DoubleValue(Math.Exp(2 * hyp[0])));
@@ -90,13 +91,13 @@
     }
 
-    public override double GetCovariance(double[,] x, int i, int j) {
+    public double GetCovariance(double[,] x, int i, int j) {
       return scale;
     }
 
-    public override IEnumerable<double> GetGradient(double[,] x, int i, int j) {
+    public IEnumerable<double> GetGradient(double[,] x, int i, int j) {
       yield return 2.0 * scale;
     }
 
-    public override double GetCrossCovariance(double[,] x, double[,] xt, int i, int j) {
+    public double GetCrossCovariance(double[,] x, double[,] xt, int i, int j) {
       return scale;
     }
Index: unk/sources/HeuristicLab.Algorithms.DataAnalysis/3.4/GaussianProcess/CovarianceFunction.cs
===================================================================
--- /trunk/sources/HeuristicLab.Algorithms.DataAnalysis/3.4/GaussianProcess/CovarianceFunction.cs	(revision 8611)
+++ 	(revision )
@@ -1,98 +1,0 @@
-﻿#region License Information
-/* HeuristicLab
- * Copyright (C) 2002-2012 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.Collections.Generic;
-using HeuristicLab.Common;
-using HeuristicLab.Core;
-using HeuristicLab.Data;
-using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
-
-namespace HeuristicLab.Algorithms.DataAnalysis {
-  [StorableClass]
-  // base class for covariance functions
-  public abstract class CovarianceFunction : ParameterizedNamedItem, ICovarianceFunction {
-    [StorableConstructor]
-    protected CovarianceFunction(bool deserializing)
-      : base(deserializing) {
-    }
-
-    protected CovarianceFunction(CovarianceFunction original, Cloner cloner)
-      : base(original, cloner) {
-    }
-
-    protected CovarianceFunction()
-      : base() {
-      Name = ItemName;
-      Description = ItemDescription;
-    }
-
-    protected void SetNullableDoubleParameter(IValueParameter<DoubleValue> parameter, double? value) {
-      if (value.HasValue) {
-        parameter.Value = new DoubleValue(value.Value);
-      } else {
-        parameter.Value = null;
-      }
-    }
-
-    protected double? GetNullableDoubleParameter(IValueParameter<DoubleValue> parameter) {
-      return parameter.Value == null ? (double?)null : parameter.Value.Value;
-    }
-
-    protected void AttachValueChangeHandler<T, U>(IValueParameter<T> parameter, Action action)
-      where T : ValueTypeValue<U>
-      where U : struct {
-      parameter.ValueChanged += (sender, args) => {
-        if (parameter.Value != null) {
-          parameter.Value.ValueChanged += (s, a) => action();
-          action();
-        }
-      };
-      if (parameter.Value != null) {
-        parameter.Value.ValueChanged += (s, a) => action();
-      }
-    }
-
-    protected void AttachArrayChangeHandler<T, U>(IValueParameter<T> parameter, Action action)
-      where T : ValueTypeArray<U>
-      where U : struct {
-      parameter.ValueChanged += (sender, args) => {
-        if (parameter.Value != null) {
-          parameter.Value.ItemChanged += (s, a) => action();
-          parameter.Value.Reset += (s, a) => action();
-          action();
-        }
-      };
-      if (parameter.Value != null) {
-        parameter.Value.ItemChanged += (s, a) => action();
-        parameter.Value.Reset += (s, a) => action();
-      }
-
-    }
-
-    public abstract int GetNumberOfParameters(int numberOfVariables);
-    public abstract void SetParameter(double[] hyp);
-    public abstract double GetCovariance(double[,] x, int i, int j);
-    public abstract IEnumerable<double> GetGradient(double[,] x, int i, int j);
-    public abstract double GetCrossCovariance(double[,] x, double[,] xt, int i, int j);
-
-  }
-}
Index: /trunk/sources/HeuristicLab.Algorithms.DataAnalysis/3.4/GaussianProcess/CovarianceLinear.cs
===================================================================
--- /trunk/sources/HeuristicLab.Algorithms.DataAnalysis/3.4/GaussianProcess/CovarianceLinear.cs	(revision 8611)
+++ /trunk/sources/HeuristicLab.Algorithms.DataAnalysis/3.4/GaussianProcess/CovarianceLinear.cs	(revision 8612)
@@ -29,11 +29,8 @@
   [StorableClass]
   [Item(Name = "CovarianceLinear", Description = "Linear covariance function for Gaussian processes.")]
-  public class CovarianceLinear : CovarianceFunction {
-    public override int GetNumberOfParameters(int numberOfVariables) {
-      return 0;
-    }
+  public sealed class CovarianceLinear : Item, ICovarianceFunction {
     [StorableConstructor]
-    protected CovarianceLinear(bool deserializing) : base(deserializing) { }
-    protected CovarianceLinear(CovarianceLinear original, Cloner cloner)
+    private CovarianceLinear(bool deserializing) : base(deserializing) { }
+    private CovarianceLinear(CovarianceLinear original, Cloner cloner)
       : base(original, cloner) {
     }
@@ -46,17 +43,21 @@
     }
 
-    public override void SetParameter(double[] hyp) {
+    public int GetNumberOfParameters(int numberOfVariables) {
+      return 0;
+    }
+
+    public void SetParameter(double[] hyp) {
       if (hyp.Length > 0) throw new ArgumentException("No hyperparameters are allowed for the linear covariance function.");
     }
 
-    public override double GetCovariance(double[,] x, int i, int j) {
+    public double GetCovariance(double[,] x, int i, int j) {
       return Util.ScalarProd(x, i, j);
     }
 
-    public override IEnumerable<double> GetGradient(double[,] x, int i, int j) {
+    public IEnumerable<double> GetGradient(double[,] x, int i, int j) {
       yield break;
     }
 
-    public override double GetCrossCovariance(double[,] x, double[,] xt, int i, int j) {
+    public double GetCrossCovariance(double[,] x, double[,] xt, int i, int j) {
       return Util.ScalarProd(x, i, xt, j);
     }
Index: /trunk/sources/HeuristicLab.Algorithms.DataAnalysis/3.4/GaussianProcess/CovarianceLinearArd.cs
===================================================================
--- /trunk/sources/HeuristicLab.Algorithms.DataAnalysis/3.4/GaussianProcess/CovarianceLinearArd.cs	(revision 8611)
+++ /trunk/sources/HeuristicLab.Algorithms.DataAnalysis/3.4/GaussianProcess/CovarianceLinearArd.cs	(revision 8612)
@@ -32,18 +32,16 @@
   [Item(Name = "CovarianceLinearArd",
     Description = "Linear covariance function with automatic relevance determination for Gaussian processes.")]
-  public class CovarianceLinearArd : CovarianceFunction {
+  public sealed class CovarianceLinearArd : ParameterizedNamedItem, ICovarianceFunction {
+    [Storable]
+    private double[] inverseLength;
+    [Storable]
+    private readonly HyperParameter<DoubleArray> inverseLengthParameter;
     public IValueParameter<DoubleArray> InverseLengthParameter {
       get { return inverseLengthParameter; }
     }
 
-    [Storable]
-    private HyperParameter<DoubleArray> inverseLengthParameter;
-
-    [Storable]
-    private double[] inverseLength;
-
     [StorableConstructor]
-    protected CovarianceLinearArd(bool deserializing) : base(deserializing) { }
-    protected CovarianceLinearArd(CovarianceLinearArd original, Cloner cloner)
+    private CovarianceLinearArd(bool deserializing) : base(deserializing) { }
+    private CovarianceLinearArd(CovarianceLinearArd original, Cloner cloner)
       : base(original, cloner) {
       inverseLengthParameter = cloner.Clone(original.inverseLengthParameter);
@@ -57,4 +55,7 @@
     public CovarianceLinearArd()
       : base() {
+      Name = ItemName;
+      Description = ItemDescription;
+
       inverseLengthParameter = new HyperParameter<DoubleArray>("InverseLength",
                                                                "The inverse length parameter for ARD.");
@@ -74,9 +75,9 @@
     // caching
     private void RegisterEvents() {
-      AttachArrayChangeHandler<DoubleArray, double>(inverseLengthParameter, () => { inverseLength = inverseLengthParameter.Value.ToArray(); });
+      Util.AttachArrayChangeHandler<DoubleArray, double>(inverseLengthParameter, () => { inverseLength = inverseLengthParameter.Value.ToArray(); });
     }
 
 
-    public override int GetNumberOfParameters(int numberOfVariables) {
+    public int GetNumberOfParameters(int numberOfVariables) {
       if (!inverseLengthParameter.Fixed)
         return numberOfVariables;
@@ -85,5 +86,5 @@
     }
 
-    public override void SetParameter(double[] hyp) {
+    public void SetParameter(double[] hyp) {
       if (!inverseLengthParameter.Fixed && hyp.Length > 0) {
         inverseLengthParameter.SetValue(new DoubleArray(hyp.Select(e => 1.0 / Math.Exp(e)).ToArray()));
@@ -91,9 +92,9 @@
     }
 
-    public override double GetCovariance(double[,] x, int i, int j) {
+    public double GetCovariance(double[,] x, int i, int j) {
       return Util.ScalarProd(x, i, j, inverseLength);
     }
 
-    public override IEnumerable<double> GetGradient(double[,] x, int i, int j) {
+    public IEnumerable<double> GetGradient(double[,] x, int i, int j) {
       for (int k = 0; k < inverseLength.Length; k++) {
         yield return -2.0 * x[i, k] * x[j, k] * inverseLength[k] * inverseLength[k];
@@ -101,5 +102,5 @@
     }
 
-    public override double GetCrossCovariance(double[,] x, double[,] xt, int i, int j) {
+    public double GetCrossCovariance(double[,] x, double[,] xt, int i, int j) {
       return Util.ScalarProd(x, i, xt, j, inverseLength);
     }
Index: /trunk/sources/HeuristicLab.Algorithms.DataAnalysis/3.4/GaussianProcess/CovarianceMaternIso.cs
===================================================================
--- /trunk/sources/HeuristicLab.Algorithms.DataAnalysis/3.4/GaussianProcess/CovarianceMaternIso.cs	(revision 8611)
+++ /trunk/sources/HeuristicLab.Algorithms.DataAnalysis/3.4/GaussianProcess/CovarianceMaternIso.cs	(revision 8612)
@@ -33,35 +33,36 @@
   [Item(Name = "CovarianceMaternIso",
     Description = "Matern covariance function for Gaussian processes.")]
-  public class CovarianceMaternIso : CovarianceFunction {
+  public sealed class CovarianceMaternIso : ParameterizedNamedItem, ICovarianceFunction {
+    [Storable]
+    private double inverseLength;
+    [Storable]
+    private readonly HyperParameter<DoubleValue> inverseLengthParameter;
+    public IValueParameter<DoubleValue> InverseLengthParameter {
+      get { return inverseLengthParameter; }
+    }
+
+    [Storable]
+    private double sf2;
+    [Storable]
+    private readonly HyperParameter<DoubleValue> scaleParameter;
     public IValueParameter<DoubleValue> ScaleParameter {
       get { return scaleParameter; }
     }
-    public IValueParameter<DoubleValue> InverseLengthParameter {
-      get { return inverseLengthParameter; }
-    }
+
+    [Storable]
+    private int d;
+    [Storable]
+    private readonly ConstrainedValueParameter<IntValue> dParameter;
     public IConstrainedValueParameter<IntValue> DParameter {
       get { return dParameter; }
     }
 
-    [Storable]
-    private readonly HyperParameter<DoubleValue> inverseLengthParameter;
-    [Storable]
-    private readonly HyperParameter<DoubleValue> scaleParameter;
-    [Storable]
-    private readonly ConstrainedValueParameter<IntValue> dParameter;
-
-    [Storable]
-    private double inverseLength;
-    [Storable]
-    private double sf2;
-    [Storable]
-    private int d;
 
     [StorableConstructor]
-    protected CovarianceMaternIso(bool deserializing)
+    private CovarianceMaternIso(bool deserializing)
       : base(deserializing) {
     }
 
-    protected CovarianceMaternIso(CovarianceMaternIso original, Cloner cloner)
+    private CovarianceMaternIso(CovarianceMaternIso original, Cloner cloner)
       : base(original, cloner) {
       this.scaleParameter = cloner.Clone(original.scaleParameter);
@@ -76,4 +77,7 @@
     public CovarianceMaternIso()
       : base() {
+      Name = ItemName;
+      Description = ItemDescription;
+
       inverseLengthParameter = new HyperParameter<DoubleValue>("InverseLength", "The inverse length parameter of the isometric Matern covariance function.");
       scaleParameter = new HyperParameter<DoubleValue>("Scale", "The scale parameter of the isometric Matern covariance function.");
@@ -103,10 +107,10 @@
     // caching
     private void RegisterEvents() {
-      AttachValueChangeHandler<DoubleValue, double>(inverseLengthParameter, () => { inverseLength = inverseLengthParameter.Value.Value; });
-      AttachValueChangeHandler<DoubleValue, double>(scaleParameter, () => { sf2 = scaleParameter.Value.Value; });
-      AttachValueChangeHandler<IntValue, int>(dParameter, () => { d = dParameter.Value.Value; });
+      Util.AttachValueChangeHandler<DoubleValue, double>(inverseLengthParameter, () => { inverseLength = inverseLengthParameter.Value.Value; });
+      Util.AttachValueChangeHandler<DoubleValue, double>(scaleParameter, () => { sf2 = scaleParameter.Value.Value; });
+      Util.AttachValueChangeHandler<IntValue, int>(dParameter, () => { d = dParameter.Value.Value; });
     }
 
-    public override int GetNumberOfParameters(int numberOfVariables) {
+    public int GetNumberOfParameters(int numberOfVariables) {
       return
         (inverseLengthParameter.Fixed ? 0 : 1) +
@@ -114,5 +118,5 @@
     }
 
-    public override void SetParameter(double[] hyp) {
+    public void SetParameter(double[] hyp) {
       int i = 0;
       if (!inverseLengthParameter.Fixed) {
@@ -150,5 +154,5 @@
     }
 
-    public override double GetCovariance(double[,] x, int i, int j) {
+    public double GetCovariance(double[,] x, int i, int j) {
       double dist = i == j
                    ? 0.0
@@ -157,5 +161,5 @@
     }
 
-    public override IEnumerable<double> GetGradient(double[,] x, int i, int j) {
+    public IEnumerable<double> GetGradient(double[,] x, int i, int j) {
       double dist = i == j
                    ? 0.0
@@ -166,5 +170,5 @@
     }
 
-    public override double GetCrossCovariance(double[,] x, double[,] xt, int i, int j) {
+    public double GetCrossCovariance(double[,] x, double[,] xt, int i, int j) {
       double dist = Math.Sqrt(Util.SqrDist(x, i, xt, j, Math.Sqrt(d) * inverseLength));
       return sf2 * m(dist);
Index: /trunk/sources/HeuristicLab.Algorithms.DataAnalysis/3.4/GaussianProcess/CovarianceNoise.cs
===================================================================
--- /trunk/sources/HeuristicLab.Algorithms.DataAnalysis/3.4/GaussianProcess/CovarianceNoise.cs	(revision 8611)
+++ /trunk/sources/HeuristicLab.Algorithms.DataAnalysis/3.4/GaussianProcess/CovarianceNoise.cs	(revision 8612)
@@ -24,4 +24,5 @@
 using HeuristicLab.Common;
 using HeuristicLab.Core;
+using HeuristicLab.Data;
 using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
 
@@ -30,21 +31,36 @@
   [Item(Name = "CovarianceNoise",
     Description = "Noise covariance function for Gaussian processes.")]
-  public class CovarianceNoise : Item, ICovarianceFunction {
+  public sealed class CovarianceNoise : ParameterizedNamedItem, ICovarianceFunction {
+
+
     [Storable]
     private double sf2;
-    public double Scale { get { return sf2; } }
+    [Storable]
+    private readonly HyperParameter<DoubleValue> scaleParameter;
+    public IValueParameter<DoubleValue> ScaleParameter {
+      get { return scaleParameter; }
+    }
 
     [StorableConstructor]
-    protected CovarianceNoise(bool deserializing)
+    private CovarianceNoise(bool deserializing)
       : base(deserializing) {
     }
 
-    protected CovarianceNoise(CovarianceNoise original, Cloner cloner)
+    private CovarianceNoise(CovarianceNoise original, Cloner cloner)
       : base(original, cloner) {
+      this.scaleParameter = cloner.Clone(original.scaleParameter);
       this.sf2 = original.sf2;
+      RegisterEvents();
     }
 
     public CovarianceNoise()
       : base() {
+      Name = ItemName;
+      Description = ItemDescription;
+
+      this.scaleParameter = new HyperParameter<DoubleValue>("Scale", "The scale of noise.");
+      Parameters.Add(this.scaleParameter);
+
+      RegisterEvents();
     }
 
@@ -53,10 +69,23 @@
     }
 
+    [StorableHook(HookType.AfterDeserialization)]
+    private void AfterDeserialization() {
+      RegisterEvents();
+    }
+
+    private void RegisterEvents() {
+      Util.AttachValueChangeHandler<DoubleValue, double>(scaleParameter, () => { sf2 = scaleParameter.Value.Value; });
+    }
+
     public int GetNumberOfParameters(int numberOfVariables) {
-      return 1;
+      return scaleParameter.Fixed ? 0 : 1;
     }
 
     public void SetParameter(double[] hyp) {
-      this.sf2 = Math.Exp(2 * hyp[0]);
+      if (!scaleParameter.Fixed) {
+        scaleParameter.SetValue(new DoubleValue(Math.Exp(2 * hyp[0])));
+      } else {
+        if (hyp.Length > 0) throw new ArgumentException("The length of the parameter vector does not match the number of free parameters for CovarianceNoise", "hyp");
+      }
     }
 
Index: /trunk/sources/HeuristicLab.Algorithms.DataAnalysis/3.4/GaussianProcess/CovariancePeriodic.cs
===================================================================
--- /trunk/sources/HeuristicLab.Algorithms.DataAnalysis/3.4/GaussianProcess/CovariancePeriodic.cs	(revision 8611)
+++ /trunk/sources/HeuristicLab.Algorithms.DataAnalysis/3.4/GaussianProcess/CovariancePeriodic.cs	(revision 8612)
@@ -31,33 +31,34 @@
   [StorableClass]
   [Item(Name = "CovariancePeriodic", Description = "Periodic covariance function for Gaussian processes.")]
-  public class CovariancePeriodic : CovarianceFunction {
+  public sealed class CovariancePeriodic : ParameterizedNamedItem, ICovarianceFunction {
+
+    [Storable]
+    private double scale;
+    [Storable]
+    private readonly HyperParameter<DoubleValue> scaleParameter;
     public IValueParameter<DoubleValue> ScaleParameter {
       get { return scaleParameter; }
     }
+
+    [Storable]
+    private double inverseLength;
+    [Storable]
+    private readonly HyperParameter<DoubleValue> inverseLengthParameter;
     public IValueParameter<DoubleValue> InverseLengthParameter {
       get { return inverseLengthParameter; }
     }
+
+    [Storable]
+    private double period;
+    [Storable]
+    private readonly HyperParameter<DoubleValue> periodParameter;
     public IValueParameter<DoubleValue> PeriodParameter {
       get { return periodParameter; }
     }
 
-    [Storable]
-    private HyperParameter<DoubleValue> scaleParameter;
-    [Storable]
-    private HyperParameter<DoubleValue> inverseLengthParameter;
-    [Storable]
-    private HyperParameter<DoubleValue> periodParameter;
-
-    [Storable]
-    private double scale;
-    [Storable]
-    private double inverseLength;
-    [Storable]
-    private double period;
-
 
     [StorableConstructor]
-    protected CovariancePeriodic(bool deserializing) : base(deserializing) { }
-    protected CovariancePeriodic(CovariancePeriodic original, Cloner cloner)
+    private CovariancePeriodic(bool deserializing) : base(deserializing) { }
+    private CovariancePeriodic(CovariancePeriodic original, Cloner cloner)
       : base(original, cloner) {
       this.scaleParameter = cloner.Clone(original.scaleParameter);
@@ -73,4 +74,7 @@
     public CovariancePeriodic()
       : base() {
+      Name = ItemName;
+      Description = ItemDescription;
+      
       scaleParameter = new HyperParameter<DoubleValue>("Scale", "The scale of the periodic covariance function.");
       inverseLengthParameter = new HyperParameter<DoubleValue>("InverseLength", "The inverse length parameter for the periodic covariance function.");
@@ -94,15 +98,15 @@
     // caching
     private void RegisterEvents() {
-      AttachValueChangeHandler<DoubleValue, double>(scaleParameter, () => { scale = scaleParameter.Value.Value; });
-      AttachValueChangeHandler<DoubleValue, double>(inverseLengthParameter, () => { inverseLength = inverseLengthParameter.Value.Value; });
-      AttachValueChangeHandler<DoubleValue, double>(periodParameter, () => { period = periodParameter.Value.Value; });
+      Util.AttachValueChangeHandler<DoubleValue, double>(scaleParameter, () => { scale = scaleParameter.Value.Value; });
+      Util.AttachValueChangeHandler<DoubleValue, double>(inverseLengthParameter, () => { inverseLength = inverseLengthParameter.Value.Value; });
+      Util.AttachValueChangeHandler<DoubleValue, double>(periodParameter, () => { period = periodParameter.Value.Value; });
     }
 
-    public override int GetNumberOfParameters(int numberOfVariables) {
+    public int GetNumberOfParameters(int numberOfVariables) {
       return
         (new[] { scaleParameter, inverseLengthParameter, periodParameter }).Count(p => !p.Fixed);
     }
 
-    public override void SetParameter(double[] hyp) {
+    public void SetParameter(double[] hyp) {
       int i = 0;
       if (!inverseLengthParameter.Fixed) {
@@ -121,5 +125,5 @@
     }
 
-    public override double GetCovariance(double[,] x, int i, int j) {
+    public double GetCovariance(double[,] x, int i, int j) {
       double k = i == j ? 0.0 : GetDistance(x, x, i, j);
       k = Math.PI * k / period;
@@ -130,5 +134,5 @@
     }
 
-    public override IEnumerable<double> GetGradient(double[,] x, int i, int j) {
+    public IEnumerable<double> GetGradient(double[,] x, int i, int j) {
       double v = i == j ? 0.0 : Math.PI * GetDistance(x, x, i, j) / period;
       double gradient = Math.Sin(v) * inverseLength;
@@ -140,5 +144,5 @@
     }
 
-    public override double GetCrossCovariance(double[,] x, double[,] xt, int i, int j) {
+    public double GetCrossCovariance(double[,] x, double[,] xt, int i, int j) {
       double k = GetDistance(x, xt, i, j);
       k = Math.PI * k / period;
Index: /trunk/sources/HeuristicLab.Algorithms.DataAnalysis/3.4/GaussianProcess/CovarianceProd.cs
===================================================================
--- /trunk/sources/HeuristicLab.Algorithms.DataAnalysis/3.4/GaussianProcess/CovarianceProd.cs	(revision 8611)
+++ /trunk/sources/HeuristicLab.Algorithms.DataAnalysis/3.4/GaussianProcess/CovarianceProd.cs	(revision 8612)
@@ -31,5 +31,5 @@
   [Item(Name = "CovarianceProd",
     Description = "Product covariance function for Gaussian processes.")]
-  public class CovarianceProd : Item, ICovarianceFunction {
+  public sealed class CovarianceProd : Item, ICovarianceFunction {
     [Storable]
     private ItemList<ICovarianceFunction> factors;
@@ -42,9 +42,9 @@
 
     [StorableConstructor]
-    protected CovarianceProd(bool deserializing)
+    private CovarianceProd(bool deserializing)
       : base(deserializing) {
     }
 
-    protected CovarianceProd(CovarianceProd original, Cloner cloner)
+    private CovarianceProd(CovarianceProd original, Cloner cloner)
       : base(original, cloner) {
       this.factors = cloner.Clone(original.factors);
Index: /trunk/sources/HeuristicLab.Algorithms.DataAnalysis/3.4/GaussianProcess/CovarianceRQArd.cs
===================================================================
--- /trunk/sources/HeuristicLab.Algorithms.DataAnalysis/3.4/GaussianProcess/CovarianceRQArd.cs	(revision 8611)
+++ /trunk/sources/HeuristicLab.Algorithms.DataAnalysis/3.4/GaussianProcess/CovarianceRQArd.cs	(revision 8612)
@@ -25,4 +25,5 @@
 using HeuristicLab.Common;
 using HeuristicLab.Core;
+using HeuristicLab.Data;
 using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
 
@@ -31,36 +32,65 @@
   [Item(Name = "CovarianceRQArd",
     Description = "Rational quadratic covariance function with automatic relevance determination for Gaussian processes.")]
-  public class CovarianceRQArd : Item, ICovarianceFunction {
+  public sealed class CovarianceRQArd : ParameterizedNamedItem, ICovarianceFunction {
     [Storable]
     private double sf2;
-    public double Scale { get { return sf2; } }
+    [Storable]
+    private readonly HyperParameter<DoubleValue> scaleParameter;
+    public IValueParameter<DoubleValue> ScaleParameter {
+      get { return scaleParameter; }
+    }
+
     [Storable]
     private double[] inverseLength;
-    public double[] InverseLength {
-      get {
-        if (inverseLength == null) return null;
-        double[] res = new double[inverseLength.Length];
-        Array.Copy(inverseLength, res, res.Length);
-        return res;
-      }
+    [Storable]
+    private readonly HyperParameter<DoubleArray> inverseLengthParameter;
+    public IValueParameter<DoubleArray> InverseLengthParameter {
+      get { return inverseLengthParameter; }
     }
+
     [Storable]
-    private double alpha;
-    public double Shape { get { return alpha; } }
+    private double shape;
+    [Storable]
+    private readonly HyperParameter<DoubleValue> shapeParameter;
+    public IValueParameter<DoubleValue> ShapeParameter {
+      get { return shapeParameter; }
+    }
 
     [StorableConstructor]
-    protected CovarianceRQArd(bool deserializing)
+    private CovarianceRQArd(bool deserializing)
       : base(deserializing) {
     }
 
-    protected CovarianceRQArd(CovarianceRQArd original, Cloner cloner)
+    private CovarianceRQArd(CovarianceRQArd original, Cloner cloner)
       : base(original, cloner) {
+      this.scaleParameter = cloner.Clone(original.scaleParameter);
       this.sf2 = original.sf2;
-      this.inverseLength = original.InverseLength; // array is cloned in the getter
-      this.alpha = original.alpha;
+
+      this.inverseLengthParameter = cloner.Clone(original.inverseLengthParameter);
+      if (original.inverseLength != null) {
+        this.inverseLength = new double[original.inverseLength.Length];
+        Array.Copy(original.inverseLength, inverseLength, inverseLength.Length);
+      }
+
+      this.shapeParameter = cloner.Clone(original.shapeParameter);
+      this.shape = original.shape;
+
+      RegisterEvents();
     }
 
     public CovarianceRQArd()
       : base() {
+      Name = ItemName;
+      Description = ItemDescription;
+
+      this.scaleParameter = new HyperParameter<DoubleValue>("Scale", "The scale parameter of the rational quadratic covariance function with ARD.");
+      this.inverseLengthParameter = new HyperParameter<DoubleArray>("InverseLength", "The inverse length parameter for automatic relevance determination.");
+      this.shapeParameter = new HyperParameter<DoubleValue>("Shape", "The shape parameter (alpha) of the rational quadratic covariance function with ARD.");
+
+      Parameters.Add(scaleParameter);
+      Parameters.Add(inverseLengthParameter);
+      Parameters.Add(shapeParameter);
+
+      RegisterEvents();
     }
 
@@ -69,12 +99,37 @@
     }
 
+    [StorableHook(HookType.AfterDeserialization)]
+    private void AfterDeserialization() {
+      RegisterEvents();
+    }
+
+    private void RegisterEvents() {
+      Util.AttachValueChangeHandler<DoubleValue, double>(scaleParameter, () => { sf2 = scaleParameter.Value.Value; });
+      Util.AttachValueChangeHandler<DoubleValue, double>(shapeParameter, () => { shape = shapeParameter.Value.Value; });
+      Util.AttachArrayChangeHandler<DoubleArray, double>(inverseLengthParameter, () => { inverseLength = inverseLengthParameter.Value.ToArray(); });
+    }
+
     public int GetNumberOfParameters(int numberOfVariables) {
-      return numberOfVariables + 2;
+      return
+        (scaleParameter.Fixed ? 0 : 1) +
+        (shapeParameter.Fixed ? 0 : 1) +
+        (inverseLengthParameter.Fixed ? 0 : numberOfVariables);
     }
 
     public void SetParameter(double[] hyp) {
-      this.inverseLength = hyp.Take(hyp.Length - 2).Select(e => 1.0 / Math.Exp(e)).ToArray();
-      this.sf2 = Math.Exp(2 * hyp[hyp.Length - 2]);
-      this.alpha = Math.Exp(hyp[hyp.Length - 1]);
+      int i = 0;
+      if (!scaleParameter.Fixed) {
+        scaleParameter.SetValue(new DoubleValue(Math.Exp(2 * hyp[i])));
+        i++;
+      }
+      if (!shapeParameter.Fixed) {
+        shapeParameter.SetValue(new DoubleValue(Math.Exp(hyp[i])));
+        i++;
+      }
+      if (!inverseLengthParameter.Fixed) {
+        inverseLengthParameter.SetValue(new DoubleArray(hyp.Skip(i).Select(e => 1.0 / Math.Exp(e)).ToArray()));
+        i += hyp.Skip(i).Count();
+      }
+      if (hyp.Length != i) throw new ArgumentException("The length of the parameter vector does not match the number of free parameters for CovarianceRQArd", "hyp");
     }
 
@@ -84,5 +139,5 @@
                    ? 0.0
                    : Util.SqrDist(x, i, j, inverseLength);
-      return sf2 * Math.Pow(1 + 0.5 * d / alpha, -alpha);
+      return sf2 * Math.Pow(1 + 0.5 * d / shape, -shape);
     }
 
@@ -91,15 +146,15 @@
                    ? 0.0
                    : Util.SqrDist(x, i, j, inverseLength);
-      double b = 1 + 0.5 * d / alpha;
+      double b = 1 + 0.5 * d / shape;
       for (int k = 0; k < inverseLength.Length; k++) {
-        yield return sf2 * Math.Pow(b, -alpha - 1) * Util.SqrDist(x[i, k] * inverseLength[k], x[j, k] * inverseLength[k]);
+        yield return sf2 * Math.Pow(b, -shape - 1) * Util.SqrDist(x[i, k] * inverseLength[k], x[j, k] * inverseLength[k]);
       }
-      yield return 2 * sf2 * Math.Pow(b, -alpha);
-      yield return sf2 * Math.Pow(b, -alpha) * (0.5 * d / b - alpha * Math.Log(b));
+      yield return 2 * sf2 * Math.Pow(b, -shape);
+      yield return sf2 * Math.Pow(b, -shape) * (0.5 * d / b - shape * Math.Log(b));
     }
 
     public double GetCrossCovariance(double[,] x, double[,] xt, int i, int j) {
       double d = Util.SqrDist(x, i, xt, j, inverseLength);
-      return sf2 * Math.Pow(1 + 0.5 * d / alpha, -alpha);
+      return sf2 * Math.Pow(1 + 0.5 * d / shape, -shape);
     }
   }
Index: /trunk/sources/HeuristicLab.Algorithms.DataAnalysis/3.4/GaussianProcess/CovarianceRQiso.cs
===================================================================
--- /trunk/sources/HeuristicLab.Algorithms.DataAnalysis/3.4/GaussianProcess/CovarianceRQiso.cs	(revision 8611)
+++ /trunk/sources/HeuristicLab.Algorithms.DataAnalysis/3.4/GaussianProcess/CovarianceRQiso.cs	(revision 8612)
@@ -24,4 +24,5 @@
 using HeuristicLab.Common;
 using HeuristicLab.Core;
+using HeuristicLab.Data;
 using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
 
@@ -30,29 +31,56 @@
   [Item(Name = "CovarianceRQiso",
     Description = "Isotropic rational quadratic covariance function for Gaussian processes.")]
-  public class CovarianceRQiso : Item, ICovarianceFunction {
+  public sealed class CovarianceRQiso : ParameterizedNamedItem, ICovarianceFunction {
     [Storable]
     private double sf2;
-    public double Scale { get { return sf2; } }
+    [Storable]
+    private readonly HyperParameter<DoubleValue> scaleParameter;
+    public IValueParameter<DoubleValue> ScaleParameter { get { return scaleParameter; } }
+
     [Storable]
     private double inverseLength;
-    public double InverseLength { get { return inverseLength; } }
     [Storable]
-    private double alpha;
-    public double Shape { get { return alpha; } }
+    private readonly HyperParameter<DoubleValue> inverseLengthParameter;
+    public IValueParameter<DoubleValue> InverseLengthParameter { get { return inverseLengthParameter; } }
+
+    [Storable]
+    private double shape;
+    [Storable]
+    private readonly HyperParameter<DoubleValue> shapeParameter;
+    public IValueParameter<DoubleValue> ShapeParameter { get { return shapeParameter; } }
 
     [StorableConstructor]
-    protected CovarianceRQiso(bool deserializing)
+    private CovarianceRQiso(bool deserializing)
       : base(deserializing) {
     }
 
-    protected CovarianceRQiso(CovarianceRQiso original, Cloner cloner)
+    private CovarianceRQiso(CovarianceRQiso original, Cloner cloner)
       : base(original, cloner) {
       this.sf2 = original.sf2;
+      this.scaleParameter = cloner.Clone(original.scaleParameter);
+
       this.inverseLength = original.inverseLength;
-      this.alpha = original.alpha;
+      this.inverseLengthParameter = cloner.Clone(original.inverseLengthParameter);
+
+      this.shape = original.shape;
+      this.shapeParameter = cloner.Clone(original.shapeParameter);
+
+      RegisterEvents();
     }
 
     public CovarianceRQiso()
       : base() {
+      Name = ItemName;
+      Description = ItemDescription;
+
+      this.scaleParameter = new HyperParameter<DoubleValue>("Scale", "The scale parameter of the isometric rational quadratic covariance function.");
+      this.inverseLengthParameter = new HyperParameter<DoubleValue>("InverseLength", "The inverse length parameter of the isometric rational quadratic covariance function.");
+      this.shapeParameter = new HyperParameter<DoubleValue>("Shape", "The shape parameter (alpha) of the isometric rational quadratic covariance function.");
+
+      Parameters.Add(scaleParameter);
+      Parameters.Add(inverseLengthParameter);
+      Parameters.Add(shapeParameter);
+
+      RegisterEvents();
     }
 
@@ -61,13 +89,37 @@
     }
 
+    [StorableHook(HookType.AfterDeserialization)]
+    private void AfterDeserialization() {
+      RegisterEvents();
+    }
+
+    private void RegisterEvents() {
+      Util.AttachValueChangeHandler<DoubleValue, double>(scaleParameter, () => { sf2 = scaleParameter.Value.Value; });
+      Util.AttachValueChangeHandler<DoubleValue, double>(inverseLengthParameter, () => { inverseLength = inverseLengthParameter.Value.Value; });
+      Util.AttachValueChangeHandler<DoubleValue, double>(shapeParameter, () => { shape = shapeParameter.Value.Value; });
+    }
+
     public int GetNumberOfParameters(int numberOfVariables) {
-      return 3;
+      return
+        (scaleParameter.Fixed ? 0 : 1) +
+        (inverseLengthParameter.Fixed ? 0 : 1) +
+        (shapeParameter.Fixed ? 0 : 1);
     }
 
     public void SetParameter(double[] hyp) {
-      if (hyp.Length != 3) throw new ArgumentException("CovarianceRQiso has three hyperparameters", "k");
-      this.inverseLength = 1.0 / Math.Exp(hyp[0]);
-      this.sf2 = Math.Exp(2 * hyp[1]);
-      this.alpha = Math.Exp(hyp[2]);
+      int i = 0;
+      if (!scaleParameter.Fixed) {
+        scaleParameter.SetValue(new DoubleValue(Math.Exp(2 * hyp[i])));
+        i++;
+      }
+      if (!shapeParameter.Fixed) {
+        shapeParameter.SetValue(new DoubleValue(Math.Exp(hyp[i])));
+        i++;
+      }
+      if (!inverseLengthParameter.Fixed) {
+        inverseLengthParameter.SetValue(new DoubleValue(1.0 / Math.Exp(hyp[i])));
+        i++;
+      }
+      if (hyp.Length != i) throw new ArgumentException("The length of the parameter vector does not match the number of free parameters for CovarianceRQiso", "hyp");
     }
 
@@ -77,5 +129,5 @@
                    ? 0.0
                    : Util.SqrDist(x, i, j, inverseLength);
-      return sf2 * Math.Pow(1 + 0.5 * d / alpha, -alpha);
+      return sf2 * Math.Pow(1 + 0.5 * d / shape, -shape);
     }
 
@@ -85,13 +137,13 @@
                    : Util.SqrDist(x, i, j, inverseLength);
 
-      double b = 1 + 0.5 * d / alpha;
-      yield return sf2 * Math.Pow(b, -alpha - 1) * d;
-      yield return 2 * sf2 * Math.Pow(b, -alpha);
-      yield return sf2 * Math.Pow(b, -alpha) * (0.5 * d / b - alpha * Math.Log(b));
+      double b = 1 + 0.5 * d / shape;
+      yield return sf2 * Math.Pow(b, -shape - 1) * d;
+      yield return 2 * sf2 * Math.Pow(b, -shape);
+      yield return sf2 * Math.Pow(b, -shape) * (0.5 * d / b - shape * Math.Log(b));
     }
 
     public double GetCrossCovariance(double[,] x, double[,] xt, int i, int j) {
       double d = Util.SqrDist(x, i, xt, j, inverseLength);
-      return sf2 * Math.Pow(1 + 0.5 * d / alpha, -alpha);
+      return sf2 * Math.Pow(1 + 0.5 * d / shape, -shape);
     }
   }
Index: /trunk/sources/HeuristicLab.Algorithms.DataAnalysis/3.4/GaussianProcess/CovarianceSEard.cs
===================================================================
--- /trunk/sources/HeuristicLab.Algorithms.DataAnalysis/3.4/GaussianProcess/CovarianceSEard.cs	(revision 8611)
+++ /trunk/sources/HeuristicLab.Algorithms.DataAnalysis/3.4/GaussianProcess/CovarianceSEard.cs	(revision 8612)
@@ -25,4 +25,5 @@
 using HeuristicLab.Common;
 using HeuristicLab.Core;
+using HeuristicLab.Data;
 using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
 
@@ -30,32 +31,44 @@
   [StorableClass]
   [Item(Name = "CovarianceSEard", Description = "Squared exponential covariance function with automatic relevance determination for Gaussian processes.")]
-  public class CovarianceSEard : Item, ICovarianceFunction {
+  public sealed class CovarianceSEard : ParameterizedNamedItem, ICovarianceFunction {
     [Storable]
     private double sf2;
-    public double Scale { get { return sf2; } }
+    [Storable]
+    private readonly HyperParameter<DoubleValue> scaleParameter;
+    public IValueParameter<DoubleValue> ScaleParameter { get { return scaleParameter; } }
 
     [Storable]
     private double[] inverseLength;
-    public double[] InverseLength {
-      get {
-        if (inverseLength == null) return new double[0];
-        var copy = new double[inverseLength.Length];
-        Array.Copy(inverseLength, copy, copy.Length);
-        return copy;
+    [Storable]
+    private readonly HyperParameter<DoubleArray> inverseLengthParameter;
+    public IValueParameter<DoubleArray> InverseLengthParameter { get { return inverseLengthParameter; } }
+
+    [StorableConstructor]
+    private CovarianceSEard(bool deserializing) : base(deserializing) { }
+    private CovarianceSEard(CovarianceSEard original, Cloner cloner)
+      : base(original, cloner) {
+      this.sf2 = original.sf2;
+      this.scaleParameter = cloner.Clone(original.scaleParameter);
+
+      if (original.inverseLength != null) {
+        this.inverseLength = new double[original.inverseLength.Length];
+        Array.Copy(original.inverseLength, this.inverseLength, this.inverseLength.Length);
       }
-    }
+      this.inverseLengthParameter = cloner.Clone(original.inverseLengthParameter);
 
-    public int GetNumberOfParameters(int numberOfVariables) {
-      return numberOfVariables + 1;
-    }
-    [StorableConstructor]
-    protected CovarianceSEard(bool deserializing) : base(deserializing) { }
-    protected CovarianceSEard(CovarianceSEard original, Cloner cloner)
-      : base(original, cloner) {
-      this.inverseLength = original.InverseLength; // array is cloned in the getter
-      this.sf2 = original.sf2;
+      RegisterEvents();
     }
     public CovarianceSEard()
       : base() {
+      Name = ItemName;
+      Description = ItemDescription;
+
+      this.scaleParameter = new HyperParameter<DoubleValue>("Scale", "The scale parameter of the squared exponential covariance function with ARD.");
+      this.inverseLengthParameter = new HyperParameter<DoubleArray>("InverseLength", "The inverse length parameter for automatic relevance determination.");
+
+      Parameters.Add(scaleParameter);
+      Parameters.Add(inverseLengthParameter);
+
+      RegisterEvents();
     }
 
@@ -64,7 +77,35 @@
     }
 
+    [StorableHook(HookType.AfterDeserialization)]
+    private void AfterDeserialization() {
+      RegisterEvents();
+    }
+
+    private void RegisterEvents() {
+      Util.AttachValueChangeHandler<DoubleValue, double>(scaleParameter, () => { sf2 = scaleParameter.Value.Value; });
+      Util.AttachArrayChangeHandler<DoubleArray, double>(inverseLengthParameter, () => {
+        inverseLength =
+          inverseLengthParameter.Value.ToArray();
+      });
+    }
+
+    public int GetNumberOfParameters(int numberOfVariables) {
+      return
+        (scaleParameter.Fixed ? 0 : 1) +
+        (inverseLengthParameter.Fixed ? 0 : numberOfVariables);
+    }
+
+
     public void SetParameter(double[] hyp) {
-      this.inverseLength = hyp.Take(hyp.Length - 1).Select(p => 1.0 / Math.Exp(p)).ToArray();
-      this.sf2 = Math.Exp(2 * hyp[hyp.Length - 1]);
+      int i = 0;
+      if (!scaleParameter.Fixed) {
+        scaleParameter.SetValue(new DoubleValue(Math.Exp(2 * hyp[i])));
+        i++;
+      }
+      if (!inverseLengthParameter.Fixed) {
+        inverseLengthParameter.SetValue(new DoubleArray(hyp.Skip(i).Select(e => 1.0 / Math.Exp(e)).ToArray()));
+        i += hyp.Skip(i).Count();
+      }
+      if (hyp.Length != i) throw new ArgumentException("The length of the parameter vector does not match the number of free parameters for CovariancSEard", "hyp");
     }
 
Index: /trunk/sources/HeuristicLab.Algorithms.DataAnalysis/3.4/GaussianProcess/CovarianceSEiso.cs
===================================================================
--- /trunk/sources/HeuristicLab.Algorithms.DataAnalysis/3.4/GaussianProcess/CovarianceSEiso.cs	(revision 8611)
+++ /trunk/sources/HeuristicLab.Algorithms.DataAnalysis/3.4/GaussianProcess/CovarianceSEiso.cs	(revision 8612)
@@ -24,4 +24,5 @@
 using HeuristicLab.Common;
 using HeuristicLab.Core;
+using HeuristicLab.Data;
 using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
 
@@ -30,25 +31,45 @@
   [Item(Name = "CovarianceSEiso",
     Description = "Isotropic squared exponential covariance function for Gaussian processes.")]
-  public class CovarianceSEiso : Item, ICovarianceFunction {
+  public sealed class CovarianceSEiso : ParameterizedNamedItem, ICovarianceFunction {
     [Storable]
     private double sf2;
-    public double Scale { get { return sf2; } }
+    [Storable]
+    private readonly HyperParameter<DoubleValue> scaleParameter;
+    public IValueParameter<DoubleValue> ScaleParameter { get { return scaleParameter; } }
+
     [Storable]
     private double inverseLength;
-    public double InverseLength { get { return inverseLength; } }
+    [Storable]
+    private readonly HyperParameter<DoubleValue> inverseLengthParameter;
+    public IValueParameter<DoubleValue> InverseLengthParameter { get { return inverseLengthParameter; } }
 
     [StorableConstructor]
-    protected CovarianceSEiso(bool deserializing)
+    private CovarianceSEiso(bool deserializing)
       : base(deserializing) {
     }
 
-    protected CovarianceSEiso(CovarianceSEiso original, Cloner cloner)
+    private CovarianceSEiso(CovarianceSEiso original, Cloner cloner)
       : base(original, cloner) {
       this.sf2 = original.sf2;
+      this.scaleParameter = cloner.Clone(original.scaleParameter);
+
       this.inverseLength = original.inverseLength;
+      this.inverseLengthParameter = cloner.Clone(original.inverseLengthParameter);
+
+      RegisterEvents();
     }
 
     public CovarianceSEiso()
       : base() {
+      Name = ItemName;
+      Description = ItemDescription;
+
+      this.scaleParameter = new HyperParameter<DoubleValue>("Scale", "The scale parameter of the isometric squared exponential covariance function.");
+      this.inverseLengthParameter = new HyperParameter<DoubleValue>("InverseLength", "The inverse length parameter of the isometric squared exponential covariance function.");
+
+      Parameters.Add(scaleParameter);
+      Parameters.Add(inverseLengthParameter);
+
+      RegisterEvents();
     }
 
@@ -57,12 +78,31 @@
     }
 
+    [StorableHook(HookType.AfterDeserialization)]
+    private void AfterDeserialization() {
+      RegisterEvents();
+    }
+
+    private void RegisterEvents() {
+      Util.AttachValueChangeHandler<DoubleValue, double>(scaleParameter, () => { sf2 = scaleParameter.Value.Value; });
+      Util.AttachValueChangeHandler<DoubleValue, double>(inverseLengthParameter, () => { inverseLength = inverseLengthParameter.Value.Value; });
+    }
+
     public int GetNumberOfParameters(int numberOfVariables) {
-      return 2;
+      return
+        (scaleParameter.Fixed ? 0 : 1) +
+        (inverseLengthParameter.Fixed ? 0 : 1);
     }
 
     public void SetParameter(double[] hyp) {
-      if (hyp.Length != 2) throw new ArgumentException("CovarianceSEiso has two hyperparameters", "k");
-      this.inverseLength = 1.0 / Math.Exp(hyp[0]);
-      this.sf2 = Math.Exp(2 * hyp[1]);
+      int i = 0;
+      if (!inverseLengthParameter.Fixed) {
+        inverseLengthParameter.SetValue(new DoubleValue(1.0 / Math.Exp(hyp[i])));
+        i++;
+      }
+      if (!scaleParameter.Fixed) {
+        scaleParameter.SetValue(new DoubleValue(Math.Exp(2 * hyp[i])));
+        i++;
+      }
+      if (hyp.Length != i) throw new ArgumentException("The length of the parameter vector does not match the number of free parameters for CovarianceSEiso", "hyp");
     }
 
Index: /trunk/sources/HeuristicLab.Algorithms.DataAnalysis/3.4/GaussianProcess/CovarianceSum.cs
===================================================================
--- /trunk/sources/HeuristicLab.Algorithms.DataAnalysis/3.4/GaussianProcess/CovarianceSum.cs	(revision 8611)
+++ /trunk/sources/HeuristicLab.Algorithms.DataAnalysis/3.4/GaussianProcess/CovarianceSum.cs	(revision 8612)
@@ -31,5 +31,5 @@
   [Item(Name = "CovarianceSum",
     Description = "Sum covariance function for Gaussian processes.")]
-  public class CovarianceSum : Item, ICovarianceFunction {
+  public sealed class CovarianceSum : Item, ICovarianceFunction {
     [Storable]
     private ItemList<ICovarianceFunction> terms;
@@ -42,9 +42,9 @@
 
     [StorableConstructor]
-    protected CovarianceSum(bool deserializing)
+    private CovarianceSum(bool deserializing)
       : base(deserializing) {
     }
 
-    protected CovarianceSum(CovarianceSum original, Cloner cloner)
+    private CovarianceSum(CovarianceSum original, Cloner cloner)
       : base(original, cloner) {
       this.terms = cloner.Clone(original.terms);
Index: /trunk/sources/HeuristicLab.Algorithms.DataAnalysis/3.4/GaussianProcess/GaussianProcessModel.cs
===================================================================
--- /trunk/sources/HeuristicLab.Algorithms.DataAnalysis/3.4/GaussianProcess/GaussianProcessModel.cs	(revision 8611)
+++ /trunk/sources/HeuristicLab.Algorithms.DataAnalysis/3.4/GaussianProcess/GaussianProcessModel.cs	(revision 8612)
@@ -137,6 +137,4 @@
       l = new double[n, n];
 
-      meanFunction.SetData(x);
-
       // calculate means and covariances
       double[] m = meanFunction.GetMean(x);
@@ -235,5 +233,4 @@
       int n = x.GetLength(0);
       var Ks = new double[newN, n];
-      meanFunction.SetData(newX);
       var ms = meanFunction.GetMean(newX);
       for (int i = 0; i < newN; i++) {
Index: /trunk/sources/HeuristicLab.Algorithms.DataAnalysis/3.4/GaussianProcess/HyperParameter.cs
===================================================================
--- /trunk/sources/HeuristicLab.Algorithms.DataAnalysis/3.4/GaussianProcess/HyperParameter.cs	(revision 8611)
+++ /trunk/sources/HeuristicLab.Algorithms.DataAnalysis/3.4/GaussianProcess/HyperParameter.cs	(revision 8612)
@@ -29,5 +29,5 @@
   [StorableClass]
   [Item(Name = "HyperParameter", Description = "Represents a hyperparameter for Gaussian processes.")]
-  public class HyperParameter<T> : OptionalValueParameter<T>, IValueParameter<T> where T : class, IItem {
+  internal class HyperParameter<T> : OptionalValueParameter<T>, IValueParameter<T> where T : class, IItem {
 
     [Storable]
Index: /trunk/sources/HeuristicLab.Algorithms.DataAnalysis/3.4/GaussianProcess/IMeanFunction.cs
===================================================================
--- /trunk/sources/HeuristicLab.Algorithms.DataAnalysis/3.4/GaussianProcess/IMeanFunction.cs	(revision 8611)
+++ /trunk/sources/HeuristicLab.Algorithms.DataAnalysis/3.4/GaussianProcess/IMeanFunction.cs	(revision 8612)
@@ -25,5 +25,4 @@
     int GetNumberOfParameters(int numberOfVariables);
     void SetParameter(double[] hyp);
-    void SetData(double[,] x);
     double[] GetMean(double[,] x);
     double[] GetGradients(int k, double[,] x);
Index: /trunk/sources/HeuristicLab.Algorithms.DataAnalysis/3.4/GaussianProcess/MeanConst.cs
===================================================================
--- /trunk/sources/HeuristicLab.Algorithms.DataAnalysis/3.4/GaussianProcess/MeanConst.cs	(revision 8611)
+++ /trunk/sources/HeuristicLab.Algorithms.DataAnalysis/3.4/GaussianProcess/MeanConst.cs	(revision 8612)
@@ -24,4 +24,5 @@
 using HeuristicLab.Common;
 using HeuristicLab.Core;
+using HeuristicLab.Data;
 using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
 
@@ -29,28 +30,51 @@
   [StorableClass]
   [Item(Name = "MeanConst", Description = "Constant mean function for Gaussian processes.")]
-  public class MeanConst : Item, IMeanFunction {
+  public sealed class MeanConst : ParameterizedNamedItem, IMeanFunction {
     [Storable]
     private double c;
-    public double Value { get { return c; } }
+    [Storable]
+    private readonly HyperParameter<DoubleValue> valueParameter;
+    public IValueParameter<DoubleValue> ValueParameter { get { return valueParameter; } }
 
-    public int GetNumberOfParameters(int numberOfVariables) {
-      return 1;
-    }
     [StorableConstructor]
-    protected MeanConst(bool deserializing) : base(deserializing) { }
-    protected MeanConst(MeanConst original, Cloner cloner)
+    private MeanConst(bool deserializing) : base(deserializing) { }
+    private MeanConst(MeanConst original, Cloner cloner)
       : base(original, cloner) {
       this.c = original.c;
+      this.valueParameter = cloner.Clone(original.valueParameter);
+      RegisterEvents();
     }
     public MeanConst()
       : base() {
+      this.name = ItemName;
+      this.description = ItemDescription;
+
+      this.valueParameter = new HyperParameter<DoubleValue>("Value", "The constant value for the constant mean function.");
+      Parameters.Add(valueParameter);
+      RegisterEvents();
+    }
+
+    public override IDeepCloneable Clone(Cloner cloner) {
+      return new MeanConst(this, cloner);
+    }
+
+    [StorableHook(HookType.AfterDeserialization)]
+    private void AfterDeserialization() {
+      RegisterEvents();
+    }
+
+    private void RegisterEvents() {
+      Util.AttachValueChangeHandler<DoubleValue, double>(valueParameter, () => { c = valueParameter.Value.Value; });
+    }
+
+    public int GetNumberOfParameters(int numberOfVariables) {
+      return valueParameter.Fixed ? 0 : 1;
     }
 
     public void SetParameter(double[] hyp) {
-      if (hyp.Length != 1) throw new ArgumentException("Only one hyper-parameter allowed for constant mean function.", "hyp");
-      this.c = hyp[0];
-    }
-    public void SetData(double[,] x) {
-      // nothing to do
+      if (!valueParameter.Fixed) {
+        valueParameter.SetValue(new DoubleValue(hyp[0]));
+      } else if (hyp.Length > 0)
+        throw new ArgumentException("The length of the parameter vector does not match the number of free parameters for the constant mean function.", "hyp");
     }
 
@@ -63,8 +87,4 @@
       return Enumerable.Repeat(1.0, x.GetLength(0)).ToArray();
     }
-
-    public override IDeepCloneable Clone(Cloner cloner) {
-      return new MeanConst(this, cloner);
-    }
   }
 }
Index: /trunk/sources/HeuristicLab.Algorithms.DataAnalysis/3.4/GaussianProcess/MeanLinear.cs
===================================================================
--- /trunk/sources/HeuristicLab.Algorithms.DataAnalysis/3.4/GaussianProcess/MeanLinear.cs	(revision 8611)
+++ /trunk/sources/HeuristicLab.Algorithms.DataAnalysis/3.4/GaussianProcess/MeanLinear.cs	(revision 8612)
@@ -19,8 +19,10 @@
  */
 #endregion
+
 using System;
 using System.Linq;
 using HeuristicLab.Common;
 using HeuristicLab.Core;
+using HeuristicLab.Data;
 using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
 
@@ -28,48 +30,62 @@
   [StorableClass]
   [Item(Name = "MeanLinear", Description = "Linear mean function for Gaussian processes.")]
-  public class MeanLinear : Item, IMeanFunction {
+  public sealed class MeanLinear : ParameterizedNamedItem, IMeanFunction {
     [Storable]
-    private double[] alpha;
-    public double[] Weights {
-      get {
-        if (alpha == null) return new double[0];
-        var copy = new double[alpha.Length];
-        Array.Copy(alpha, copy, copy.Length);
-        return copy;
+    private double[] weights;
+    [Storable]
+    private readonly HyperParameter<DoubleArray> weightsParameter;
+    public IValueParameter<DoubleArray> WeightsParameter { get { return weightsParameter; } }
+
+    [StorableConstructor]
+    private MeanLinear(bool deserializing) : base(deserializing) { }
+    private MeanLinear(MeanLinear original, Cloner cloner)
+      : base(original, cloner) {
+      if (original.weights != null) {
+        this.weights = new double[original.weights.Length];
+        Array.Copy(original.weights, weights, original.weights.Length);
       }
-    }
-    public int GetNumberOfParameters(int numberOfVariables) {
-      return numberOfVariables;
-    }
-    [StorableConstructor]
-    protected MeanLinear(bool deserializing) : base(deserializing) { }
-    protected MeanLinear(MeanLinear original, Cloner cloner)
-      : base(original, cloner) {
-      if (original.alpha != null) {
-        this.alpha = new double[original.alpha.Length];
-        Array.Copy(original.alpha, alpha, original.alpha.Length);
-      }
+      weightsParameter = cloner.Clone(original.weightsParameter);
+      RegisterEvents();
     }
     public MeanLinear()
       : base() {
+      this.weightsParameter = new HyperParameter<DoubleArray>("Weights", "The weights parameter for the linear mean function.");
+      Parameters.Add(weightsParameter);
+      RegisterEvents();
+    }
+
+    public override IDeepCloneable Clone(Cloner cloner) {
+      return new MeanLinear(this, cloner);
+    }
+
+    [StorableHook(HookType.AfterDeserialization)]
+    private void AfterDeserialization() {
+      RegisterEvents();
+    }
+
+    private void RegisterEvents() {
+      Util.AttachArrayChangeHandler<DoubleArray, double>(weightsParameter, () => {
+        weights = weightsParameter.Value.ToArray();
+      });
+    }
+
+    public int GetNumberOfParameters(int numberOfVariables) {
+      return weightsParameter.Fixed ? 0 : numberOfVariables;
     }
 
     public void SetParameter(double[] hyp) {
-      this.alpha = new double[hyp.Length];
-      Array.Copy(hyp, alpha, hyp.Length);
-    }
-    public void SetData(double[,] x) {
-      // nothing to do
+      if (!weightsParameter.Fixed) {
+        weightsParameter.SetValue(new DoubleArray(hyp));
+      } else if (hyp.Length != 0) throw new ArgumentException("The length of the parameter vector does not match the number of free parameters for the linear mean function.", "hyp");
     }
 
     public double[] GetMean(double[,] x) {
       // sanity check
-      if (alpha.Length != x.GetLength(1)) throw new ArgumentException("The number of hyperparameters must match the number of variables for the linear mean function.");
+      if (weights.Length != x.GetLength(1)) throw new ArgumentException("The number of hyperparameters must match the number of variables for the linear mean function.");
       int cols = x.GetLength(1);
       int n = x.GetLength(0);
       return (from i in Enumerable.Range(0, n)
-              let rowVector = from j in Enumerable.Range(0, cols)
-                              select x[i, j]
-              select Util.ScalarProd(alpha, rowVector))
+              let rowVector = Enumerable.Range(0, cols).Select(j => x[i, j])
+              select Util.ScalarProd(weights, rowVector))
         .ToArray();
     }
@@ -79,10 +95,5 @@
       int n = x.GetLength(0);
       if (k > cols) throw new ArgumentException();
-      return (from r in Enumerable.Range(0, n)
-              select x[r, k]).ToArray();
-    }
-
-    public override IDeepCloneable Clone(Cloner cloner) {
-      return new MeanLinear(this, cloner);
+      return (Enumerable.Range(0, n).Select(r => x[r, k])).ToArray();
     }
   }
Index: /trunk/sources/HeuristicLab.Algorithms.DataAnalysis/3.4/GaussianProcess/MeanProd.cs
===================================================================
--- /trunk/sources/HeuristicLab.Algorithms.DataAnalysis/3.4/GaussianProcess/MeanProd.cs	(revision 8611)
+++ /trunk/sources/HeuristicLab.Algorithms.DataAnalysis/3.4/GaussianProcess/MeanProd.cs	(revision 8612)
@@ -27,5 +27,5 @@
   [StorableClass]
   [Item(Name = "MeanProd", Description = "Product of mean functions for Gaussian processes.")]
-  public class MeanProd : Item, IMeanFunction {
+  public sealed class MeanProd : Item, IMeanFunction {
     [Storable]
     private ItemList<IMeanFunction> factors;
@@ -38,15 +38,10 @@
     }
 
-    public int GetNumberOfParameters(int numberOfVariables) {
-      this.numberOfVariables = numberOfVariables;
-      return factors.Select(t => t.GetNumberOfParameters(numberOfVariables)).Sum();
-    }
-
     [StorableConstructor]
-    protected MeanProd(bool deserializing)
+    private MeanProd(bool deserializing)
       : base(deserializing) {
     }
 
-    protected MeanProd(MeanProd original, Cloner cloner)
+    private MeanProd(MeanProd original, Cloner cloner)
       : base(original, cloner) {
       this.factors = cloner.Clone(original.factors);
@@ -56,4 +51,12 @@
     public MeanProd() {
       this.factors = new ItemList<IMeanFunction>();
+    }
+    public override IDeepCloneable Clone(Cloner cloner) {
+      return new MeanProd(this, cloner);
+    }
+
+    public int GetNumberOfParameters(int numberOfVariables) {
+      this.numberOfVariables = numberOfVariables;
+      return factors.Select(t => t.GetNumberOfParameters(numberOfVariables)).Sum();
     }
 
@@ -65,8 +68,4 @@
         offset += numberOfParameters;
       }
-    }
-
-    public void SetData(double[,] x) {
-      foreach (var t in factors) t.SetData(x);
     }
 
@@ -102,8 +101,4 @@
       return res;
     }
-
-    public override IDeepCloneable Clone(Cloner cloner) {
-      return new MeanProd(this, cloner);
-    }
   }
 }
Index: /trunk/sources/HeuristicLab.Algorithms.DataAnalysis/3.4/GaussianProcess/MeanSum.cs
===================================================================
--- /trunk/sources/HeuristicLab.Algorithms.DataAnalysis/3.4/GaussianProcess/MeanSum.cs	(revision 8611)
+++ /trunk/sources/HeuristicLab.Algorithms.DataAnalysis/3.4/GaussianProcess/MeanSum.cs	(revision 8612)
@@ -27,5 +27,5 @@
   [StorableClass]
   [Item(Name = "MeanSum", Description = "Sum of mean functions for Gaussian processes.")]
-  public class MeanSum : Item, IMeanFunction {
+  public sealed class MeanSum : Item, IMeanFunction {
     [Storable]
     private ItemList<IMeanFunction> terms;
@@ -37,11 +37,7 @@
     }
 
-    public int GetNumberOfParameters(int numberOfVariables) {
-      this.numberOfVariables = numberOfVariables;
-      return terms.Select(t => t.GetNumberOfParameters(numberOfVariables)).Sum();
-    }
     [StorableConstructor]
-    protected MeanSum(bool deserializing) : base(deserializing) { }
-    protected MeanSum(MeanSum original, Cloner cloner)
+    private MeanSum(bool deserializing) : base(deserializing) { }
+    private MeanSum(MeanSum original, Cloner cloner)
       : base(original, cloner) {
       this.terms = cloner.Clone(original.terms);
@@ -50,4 +46,13 @@
     public MeanSum() {
       this.terms = new ItemList<IMeanFunction>();
+    }
+
+    public override IDeepCloneable Clone(Cloner cloner) {
+      return new MeanSum(this, cloner);
+    }
+
+    public int GetNumberOfParameters(int numberOfVariables) {
+      this.numberOfVariables = numberOfVariables;
+      return terms.Select(t => t.GetNumberOfParameters(numberOfVariables)).Sum();
     }
 
@@ -59,8 +64,4 @@
         offset += numberOfParameters;
       }
-    }
-
-    public void SetData(double[,] x) {
-      foreach (var t in terms) t.SetData(x);
     }
 
@@ -82,8 +83,4 @@
       return terms[i].GetGradients(k, x);
     }
-
-    public override IDeepCloneable Clone(Cloner cloner) {
-      return new MeanSum(this, cloner);
-    }
   }
 }
Index: /trunk/sources/HeuristicLab.Algorithms.DataAnalysis/3.4/GaussianProcess/MeanZero.cs
===================================================================
--- /trunk/sources/HeuristicLab.Algorithms.DataAnalysis/3.4/GaussianProcess/MeanZero.cs	(revision 8611)
+++ /trunk/sources/HeuristicLab.Algorithms.DataAnalysis/3.4/GaussianProcess/MeanZero.cs	(revision 8612)
@@ -28,11 +28,8 @@
   [StorableClass]
   [Item(Name = "MeanZero", Description = "Constant zero mean function for Gaussian processes.")]
-  public class MeanZero : Item, IMeanFunction {
-    public int GetNumberOfParameters(int numberOfVariables) {
-      return 0;
-    }
+  public sealed class MeanZero : Item, IMeanFunction {
     [StorableConstructor]
-    protected MeanZero(bool deserializing) : base(deserializing) { }
-    protected MeanZero(MeanZero original, Cloner cloner)
+    private MeanZero(bool deserializing) : base(deserializing) { }
+    private MeanZero(MeanZero original, Cloner cloner)
       : base(original, cloner) {
     }
@@ -40,10 +37,14 @@
     }
 
+    public override IDeepCloneable Clone(Cloner cloner) {
+      return new MeanZero(this, cloner);
+    }
+
+    public int GetNumberOfParameters(int numberOfVariables) {
+      return 0;
+    }
+
     public void SetParameter(double[] hyp) {
       if (hyp.Length > 0) throw new ArgumentException("No hyper-parameters allowed for zero mean function.", "hyp");
-    }
-
-    public void SetData(double[,] x) {
-      // do nothing
     }
 
@@ -56,7 +57,4 @@
       return Enumerable.Repeat(0.0, x.GetLength(0)).ToArray();
     }
-    public override IDeepCloneable Clone(Cloner cloner) {
-      return new MeanZero(this, cloner);
-    }
   }
 }
Index: /trunk/sources/HeuristicLab.Algorithms.DataAnalysis/3.4/GaussianProcess/Util.cs
===================================================================
--- /trunk/sources/HeuristicLab.Algorithms.DataAnalysis/3.4/GaussianProcess/Util.cs	(revision 8611)
+++ /trunk/sources/HeuristicLab.Algorithms.DataAnalysis/3.4/GaussianProcess/Util.cs	(revision 8612)
@@ -20,9 +20,12 @@
 #endregion
 
+using System;
 using System.Collections.Generic;
 using System.Linq;
+using HeuristicLab.Core;
+using HeuristicLab.Data;
 
 namespace HeuristicLab.Algorithms.DataAnalysis {
-  public static class Util {
+  internal static class Util {
     public static double ScalarProd(IEnumerable<double> v, IEnumerable<double> u) {
       return v.Zip(u, (vi, ui) => vi * ui).Sum();
@@ -94,4 +97,35 @@
       return Enumerable.Range(0, rows).Select(r => x[r, c]);
     }
+
+
+    public static void AttachValueChangeHandler<T, U>(IValueParameter<T> parameter, Action action)
+      where T : ValueTypeValue<U>
+      where U : struct {
+      parameter.ValueChanged += (sender, args) => {
+        if (parameter.Value != null) {
+          parameter.Value.ValueChanged += (s, a) => action();
+          action();
+        }
+      };
+      if (parameter.Value != null) {
+        parameter.Value.ValueChanged += (s, a) => action();
+      }
+    }
+
+    public static void AttachArrayChangeHandler<T, U>(IValueParameter<T> parameter, Action action)
+      where T : ValueTypeArray<U>
+      where U : struct {
+      parameter.ValueChanged += (sender, args) => {
+        if (parameter.Value != null) {
+          parameter.Value.ItemChanged += (s, a) => action();
+          parameter.Value.Reset += (s, a) => action();
+          action();
+        }
+      };
+      if (parameter.Value != null) {
+        parameter.Value.ItemChanged += (s, a) => action();
+        parameter.Value.Reset += (s, a) => action();
+      }
+    }
   }
 }
Index: /trunk/sources/HeuristicLab.Algorithms.DataAnalysis/3.4/HeuristicLab.Algorithms.DataAnalysis-3.4.csproj
===================================================================
--- /trunk/sources/HeuristicLab.Algorithms.DataAnalysis/3.4/HeuristicLab.Algorithms.DataAnalysis-3.4.csproj	(revision 8611)
+++ /trunk/sources/HeuristicLab.Algorithms.DataAnalysis/3.4/HeuristicLab.Algorithms.DataAnalysis-3.4.csproj	(revision 8612)
@@ -121,5 +121,4 @@
     <Compile Include="FixedDataAnalysisAlgorithm.cs" />
     <Compile Include="GaussianProcess\HyperParameter.cs" />
-    <Compile Include="GaussianProcess\CovarianceFunction.cs" />
     <Compile Include="GaussianProcess\CovarianceRQArd.cs" />
     <Compile Include="GaussianProcess\CovarianceMaternIso.cs" />
Index: /trunk/sources/HeuristicLab.Tests/HeuristicLab.Algorithms.DataAnalysis-3.4/GaussianProcessFunctionsTest.cs
===================================================================
--- /trunk/sources/HeuristicLab.Tests/HeuristicLab.Algorithms.DataAnalysis-3.4/GaussianProcessFunctionsTest.cs	(revision 8611)
+++ /trunk/sources/HeuristicLab.Tests/HeuristicLab.Algorithms.DataAnalysis-3.4/GaussianProcessFunctionsTest.cs	(revision 8612)
@@ -1509,5 +1509,4 @@
       var hyp = Enumerable.Repeat(hypValue, nHyp).ToArray();
       mf.SetParameter(hyp);
-      mf.SetData(x);
 
       var m = mf.GetMean(xt);
