Index: branches/3119_AdditionalShapeConstraintFeatures/HeuristicLab.Problems.DataAnalysis/3.4/Implementation/Interval/ShapeConstraint.cs
===================================================================
--- branches/3119_AdditionalShapeConstraintFeatures/HeuristicLab.Problems.DataAnalysis/3.4/Implementation/Interval/ShapeConstraint.cs	(revision 17946)
+++ branches/3119_AdditionalShapeConstraintFeatures/HeuristicLab.Problems.DataAnalysis/3.4/Implementation/Interval/ShapeConstraint.cs	(revision 17995)
@@ -107,5 +107,5 @@
 
     [Storable]
-    private Interval threshold;
+    private Interval threshold = new Interval(0, 0);
     public Interval Threshold {
       get => threshold;
@@ -114,4 +114,31 @@
           return;
         threshold = value;
+        OnToStringChanged();
+        OnChanged();
+      }
+    }
+
+
+    [Storable]
+    private Interval targetInterval;
+    public Interval TargetInterval {
+      get => targetInterval;
+      set {
+        if (targetInterval == value)
+          return;
+        targetInterval = value;
+        OnToStringChanged();
+        OnChanged();
+      }
+    }
+
+    [Storable]
+    private Interval dynInterval = new Interval(double.NegativeInfinity, double.PositiveInfinity);
+    public Interval DynInterval {
+      get => dynInterval;
+      set {
+        if (dynInterval == value)
+          return;
+        dynInterval = value;
         OnToStringChanged();
         OnChanged();
@@ -125,22 +152,24 @@
     private void AfterDeserialization() {
       if (regions != null) regions.Changed += regions_Changed;
+      if (TargetInterval == null)
+        TargetInterval = new Interval(interval.LowerBound, interval.UpperBound);
     }
 
     // without derivation
-    public ShapeConstraint(Interval interval, double weight, Interval threshold)
+    public ShapeConstraint(Interval interval, double weight, Interval threshold, Interval dynInterval)
       : this(string.Empty, 0,
-         interval, new IntervalCollection(), weight, threshold) { }
-
-    public ShapeConstraint(Interval interval, IntervalCollection regions, double weight, Interval threshold)
+         interval, new IntervalCollection(), weight, threshold, dynInterval) { }
+
+    public ShapeConstraint(Interval interval, IntervalCollection regions, double weight, Interval threshold, Interval dynInterval)
       : this(string.Empty, 0,
-         interval, regions, weight, threshold) { }
+         interval, regions, weight, threshold, dynInterval) { }
 
     public ShapeConstraint(string variable, int numberOfDerivations,
-                              Interval interval, double weight, Interval threshold)
+                              Interval interval, double weight, Interval threshold, Interval dynInterval)
       : this(variable, numberOfDerivations,
-             interval, new IntervalCollection(), weight, threshold) { }
+             interval, new IntervalCollection(), weight, threshold, dynInterval) { }
 
     public ShapeConstraint(string variable, int numberOfDerivations,
-                              Interval interval, IntervalCollection regions, double weight, Interval threshold) {
+                              Interval interval, IntervalCollection regions, double weight, Interval threshold, Interval dynInterval) {
       Variable = variable;
       NumberOfDerivations = numberOfDerivations;
@@ -149,4 +178,6 @@
       Weight = weight;
       Threshold = threshold;
+      DynInterval = dynInterval;
+      TargetInterval = new Interval(interval.LowerBound, interval.UpperBound);
     }
 
@@ -162,6 +193,8 @@
       Regions = cloner.Clone(original.Regions);
       Weight = original.weight;
-    }
-
+      Threshold = original.Threshold;
+      DynInterval = original.DynInterval;
+      TargetInterval = original.TargetInterval;
+    }
 
     public event EventHandler Changed;
@@ -188,5 +221,5 @@
       string write(double val) => double.IsPositiveInfinity(val) ? "inf." : double.IsNegativeInfinity(val) ? "-inf." : $"{val}";
       if (!IsDerivative) {
-        expression = string.Format($"f in [{write(Interval.LowerBound)} .. {write(Interval.UpperBound)}]");
+        expression = string.Format($"f in [{write(TargetInterval.LowerBound)} .. {write(TargetInterval.UpperBound)}]");
       } else {
         var derivationString = string.Empty;
@@ -199,5 +232,5 @@
             derivationString = "³"; break;
         }
-        expression = string.Format($"∂{derivationString}f/∂{Variable}{derivationString} in [{write(Interval.LowerBound)} .. {write(Interval.UpperBound)}]");
+        expression = string.Format($"∂{derivationString}f/∂{Variable}{derivationString} in [{write(TargetInterval.LowerBound)} .. {write(TargetInterval.UpperBound)}]");
       }
 
@@ -209,6 +242,10 @@
         expression += $" weight: {weight}";
       }
+
       if (!double.IsNegativeInfinity(Threshold.LowerBound) || !double.IsPositiveInfinity(Threshold.UpperBound))
-        expression += $" threshold: [{write(Threshold.LowerBound)} .. {write(Threshold.UpperBound)}]";
+        expression += $" threshold in [{write(Threshold.LowerBound)} .. {write(Threshold.UpperBound)}]";
+
+      if (!double.IsNegativeInfinity(DynInterval.LowerBound) && !double.IsPositiveInfinity(DynInterval.UpperBound))
+        expression += $" start in [{write(DynInterval.LowerBound)} .. {write(DynInterval.UpperBound)}]";
 
       return expression;
Index: branches/3119_AdditionalShapeConstraintFeatures/HeuristicLab.Problems.DataAnalysis/3.4/Implementation/Interval/ShapeConstraintsParser.cs
===================================================================
--- branches/3119_AdditionalShapeConstraintFeatures/HeuristicLab.Problems.DataAnalysis/3.4/Implementation/Interval/ShapeConstraintsParser.cs	(revision 17946)
+++ branches/3119_AdditionalShapeConstraintFeatures/HeuristicLab.Problems.DataAnalysis/3.4/Implementation/Interval/ShapeConstraintsParser.cs	(revision 17995)
@@ -76,4 +76,5 @@
     private const string weightRegex = @"\s*(weight:\s*(?<weight>\S*))?";
     private const string thresholdRegex = @"\s*(threshold\s*in\s*(?<threshold> "+ intervalRegex + @"))?";
+    private const string dynIntervalStartRegex = @"\s*(start\s*in\s*(?<dynInterval> " + intervalRegex + @"))?";
     public static ShapeConstraint ParseFunctionRangeConstraint(string expr) {
       if (!expr.StartsWith("f")) throw new ArgumentException($"Invalid function range constraint {expr} (e.g. f in [1..2])");
@@ -90,6 +91,6 @@
       // df/d'x' in [0 .. 10] weight: 2.0
       // df / d'x' in [0..10], 'x' in [1 .. 3]
-      // df / d'x' in [0..10], 'x' in [1 .. 3], y in [10..30] weight: 1.2
-      // df / d'x' in [0..10], 'x' in [1 .. 3], y in [10..30] weight: 1.2 threshold in [-10 .. 10]
+      // df / d'x' in [0..10], 'x' in [1 .. 3], 'y' in [10..30] weight: 1.2
+      // df / d'x' in [0..10], 'x' in [1 .. 3], 'y' in [10..30] weight: 1.2 threshold in [-10 .. 10]
       var match = Regex.Match(targetConstraint,
                     @"\s*\bin\b" +
@@ -101,5 +102,6 @@
                     @")*" +
                     weightRegex +
-                    thresholdRegex
+                    thresholdRegex +
+                    dynIntervalStartRegex
                     );
 
@@ -112,16 +114,27 @@
         var interval = new Interval(lowerBound, upperBound);
         var weight = 1.0;
-        var threshold = new Interval(double.NegativeInfinity, double.PositiveInfinity);
+        var threshold = new Interval(0, 0);
+        Interval dynInterval = new Interval(double.NegativeInfinity, double.PositiveInfinity);
+        int intervalIdx = 1;
+        var lowerboundCount = match.Groups["lowerBound"].Captures.Count;
+        var upperboundCount = match.Groups["upperBound"].Captures.Count;
 
         if (match.Groups["weight"].Success && !string.IsNullOrWhiteSpace(match.Groups["weight"].Value))
           weight = ParseAndValidateDouble(match.Groups["weight"].Value);
 
-        if(match.Groups["threshold"].Success) {
-          var lowerboundCount = match.Groups["lowerBound"].Captures.Count;
-          var upperboundCount = match.Groups["upperBound"].Captures.Count;
-          var thresholdLb = ParseIntervalBounds(match.Groups["lowerBound"].Captures[lowerboundCount - 1].Value);
-          var thresholdUb = ParseIntervalBounds(match.Groups["upperBound"].Captures[upperboundCount - 1].Value);
+        if (match.Groups["dynInterval"].Success) {
+          var dynIntervalLb = ParseIntervalBounds(match.Groups["lowerBound"].Captures[lowerboundCount - intervalIdx].Value);
+          var dynIntervalUb = ParseIntervalBounds(match.Groups["upperBound"].Captures[upperboundCount - intervalIdx].Value);
+          intervalIdx++;
+          dynInterval = new Interval(dynIntervalLb, dynIntervalUb);
+        }
+
+        if (match.Groups["threshold"].Success) {
+          var thresholdLb = ParseIntervalBounds(match.Groups["lowerBound"].Captures[lowerboundCount - intervalIdx].Value);
+          var thresholdUb = ParseIntervalBounds(match.Groups["upperBound"].Captures[upperboundCount - intervalIdx].Value);
+          intervalIdx++;
           threshold = new Interval(thresholdLb, thresholdUb);
         }
+
 
         if (match.Groups["varName"].Success) {
@@ -138,7 +151,7 @@
               throw new ArgumentException($"The constraint {expr} has multiple regions of the same variable.");
           }
-          return new ShapeConstraint(interval, regions, weight, threshold);
+          return new ShapeConstraint(interval, regions, weight, threshold, dynInterval);
         } else
-          return new ShapeConstraint(interval, weight, threshold);
+          return new ShapeConstraint(interval, weight, threshold, dynInterval);
       } else
         throw new ArgumentException($"The target constraint {expr} is not valid.");
@@ -160,5 +173,6 @@
                                   @")*" +
                                 weightRegex +
-                                thresholdRegex
+                                thresholdRegex +
+                                dynIntervalStartRegex
                                 );
 
@@ -184,14 +198,24 @@
         var interval = new Interval(lowerBound, upperBound);
         var weight = 1.0;
-        var threshold = new Interval(double.NegativeInfinity, double.PositiveInfinity);
+        var threshold = new Interval(0, 0);
+        Interval dynInterval = new Interval(double.NegativeInfinity, double.PositiveInfinity);
+        int intervalIdx = 1;
+        var lowerboundCount = match.Groups["lowerBound"].Captures.Count;
+        var upperboundCount = match.Groups["upperBound"].Captures.Count;
 
         if (match.Groups["weight"].Success && !string.IsNullOrWhiteSpace(match.Groups["weight"].Value))
           weight = ParseAndValidateDouble(match.Groups["weight"].Value);
 
+        if (match.Groups["dynInterval"].Success) {
+          var dynIntervalLb = ParseIntervalBounds(match.Groups["lowerBound"].Captures[lowerboundCount - intervalIdx].Value);
+          var dynIntervalUb = ParseIntervalBounds(match.Groups["upperBound"].Captures[upperboundCount - intervalIdx].Value);
+          intervalIdx++;
+          dynInterval = new Interval(dynIntervalLb, dynIntervalUb);
+        }
+
         if (match.Groups["threshold"].Success) {
-          var lowerboundCount = match.Groups["lowerBound"].Captures.Count;
-          var upperboundCount = match.Groups["upperBound"].Captures.Count;
-          var thresholdLb = ParseIntervalBounds(match.Groups["lowerBound"].Captures[lowerboundCount - 1].Value);
-          var thresholdUb = ParseIntervalBounds(match.Groups["upperBound"].Captures[upperboundCount - 1].Value);
+          var thresholdLb = ParseIntervalBounds(match.Groups["lowerBound"].Captures[lowerboundCount - intervalIdx].Value);
+          var thresholdUb = ParseIntervalBounds(match.Groups["upperBound"].Captures[upperboundCount - intervalIdx].Value);
+          intervalIdx++;
           threshold = new Interval(thresholdLb, thresholdUb);
         }
@@ -210,7 +234,7 @@
               throw new ArgumentException($"The constraint {expr} has multiple regions of the same variable.");
           }
-          return new ShapeConstraint(variable, numberOfDerivation, interval, regions, weight, threshold);
+          return new ShapeConstraint(variable, numberOfDerivation, interval, regions, weight, threshold, dynInterval);
         } else
-          return new ShapeConstraint(variable, numberOfDerivation, interval, weight, threshold);
+          return new ShapeConstraint(variable, numberOfDerivation, interval, weight, threshold, dynInterval);
       } else
         throw new ArgumentException($"The derivation constraint {expr} is not valid.");
